clash-prelude-1.8.4: Clash: a functional hardware description language - Prelude library

Copyright | (C) 2018 Google Inc. 2019 Myrtle Software Ltd 2022-2024 QBayLogic B.V.
License | BSD2 (see the file LICENSE)
Maintainer | QBayLogic B.V. <devops@qbaylogic.com>
Safe Haskell | None
Language | Haskell2010

Clash.Signal.Trace

Contents

- Tracing functions
  - Simple
  - Tracing in a multi-clock environment
- VCD dump functions
- Replay functions
- Internal
  - Types
  - Functions

Description

Utilities for tracing signals and dumping them in various ways. Example usage:

    import Clash.Prelude hiding (writeFile)
    import Data.Text.IO  (writeFile)

    -- | Count and wrap around
    subCounter :: SystemClockResetEnable => Signal System (Index 3)
    subCounter = traceSignal1 "sub" counter
      where
        counter =
          register 0 (fmap succ' counter)

        succ' c
          | c == maxBound = 0
          | otherwise     = c + 1

    -- | Count, but only when my subcounter is wrapping around
    mainCounter :: SystemClockResetEnable => Signal System (Signed 64)
    mainCounter = traceSignal1 "main" counter
      where
        counter =
          register 0 (fmap succ' $ bundle (subCounter,counter))

        succ' (sc, c)
          | sc == maxBound = c + 1
          | otherwise      = c

    -- | Collect traces, and dump them to a VCD file.
    main :: IO ()
    main = do
      let cntrOut = exposeClockResetEnable mainCounter systemClockGen systemResetGen enableGen
      vcd <- dumpVCD (0, 100) cntrOut ["main", "sub"]
      case vcd of
        Left msg ->
          error msg
        Right contents ->
          writeFile "mainCounter.vcd" contents

Synopsis

- traceSignal1 :: forall a (dom :: Domain). (BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
- traceVecSignal1 :: forall (n :: Nat) a (dom :: Domain). (KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
- traceSignal :: forall (dom :: Domain) a. (KnownDomain dom, BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
- traceVecSignal :: forall (dom :: Domain) a (n :: Nat). (KnownDomain dom, KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
- dumpVCD :: forall a (dom :: Domain). NFDataX a => (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
- dumpReplayable :: forall a (dom :: Domain). NFDataX a => Int -> Signal dom a -> String -> IO ByteString
- replay :: forall a (dom :: Domain) (n :: Nat). (Typeable a, NFDataX a, BitPack a, KnownNat n, n ~ BitSize a) => ByteString -> Either String (Signal dom a)
- type Period = Int
- type Changed = Bool
- type Value = (Natural, Natural)
- type Width = Int
- type TraceMap = Map String (TypeRepBS, Period, Width, [Value])
- type TypeRepBS = ByteString
- traceSignal# :: forall (dom :: Domain) a. (BitPack a, NFDataX a, Typeable a) => IORef TraceMap -> Int -> String -> Signal dom a -> IO (Signal dom a)
- traceVecSignal# :: forall (dom :: Domain) (n :: Nat) a. (KnownNat n, BitPack a, NFDataX a, Typeable a) => IORef TraceMap -> Int -> String -> Signal dom (Vec (n + 1) a) -> IO (Signal dom (Vec (n + 1) a))
- dumpVCD# :: forall a (dom :: Domain). NFDataX a => IORef TraceMap -> (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
- dumpVCD## :: (Int, Int) -> TraceMap -> UTCTime -> Either String Text
- waitForTraces# :: forall a (dom :: Domain). NFDataX a => IORef TraceMap -> Signal dom a -> [String] -> IO ()
- traceMap# :: IORef TraceMap

# Tracing functions

## Simple

traceSignal1 Source #

Arguments

:: forall a (dom :: Domain). (BitPack a, NFDataX a, Typeable a) |
=> String | Name of signal in the VCD output
-> Signal dom a | Signal to trace
-> Signal dom a |

Trace a single signal. Will emit an error if a signal with the same name was previously registered.

NB: Associates the traced signal with a clock period of 1, which results in incorrect VCD files when working with circuits that have multiple clocks. Use `traceSignal` when working with circuits that have multiple clocks.

traceVecSignal1 Source #

Arguments

:: forall (n :: Nat) a (dom :: Domain). (KnownNat n, BitPack a, NFDataX a, Typeable a) |
=> String | Name of signal in debugging output. Will be appended by _0, _1, ..., _n.
-> Signal dom (Vec (n + 1) a) | Signal to trace
-> Signal dom (Vec (n + 1) a) |

Trace a single vector signal: each element in the vector will show up as a different trace. If the trace name already exists, this function will emit an error.

NB: Associates the traced signal with a clock period of 1, which results in incorrect VCD files when working with circuits that have multiple clocks. Use `traceSignal` when working with circuits that have multiple clocks.

## Tracing in a multi-clock environment

traceSignal Source #

Arguments

:: forall (dom :: Domain) a. (KnownDomain dom, BitPack a, NFDataX a, Typeable a) |
=> String | Name of signal in the VCD output
-> Signal dom a | Signal to trace
-> Signal dom a |

Trace a single signal. Will emit an error if a signal with the same name was previously registered.

NB: Works correctly when creating VCD files from traced signal in multi-clock circuits. However `traceSignal1` might be more convenient to use when the domain of your circuit is polymorphic.

traceVecSignal Source #

Arguments

:: forall (dom :: Domain) a (n :: Nat). (KnownDomain dom, KnownNat n, BitPack a, NFDataX a, Typeable a) |
=> String | Name of signal in debugging output. Will be appended by _0, _1, ..., _n.
-> Signal dom (Vec (n + 1) a) | Signal to trace
-> Signal dom (Vec (n + 1) a) |

Trace a single vector signal: each element in the vector will show up as a different trace. If the trace name already exists, this function will emit an error.

NB: Works correctly when creating VCD files from traced signal in multi-clock circuits. However `traceSignal1` might be more convenient to use when the domain of your circuit is polymorphic.

# VCD dump functions

dumpVCD Source #

Arguments

:: forall a (dom :: Domain). NFDataX a |
=> (Int, Int) | (offset, number of samples)
-> Signal dom a | (One of) the outputs of the circuit containing the traces
-> [String] | The names of the traces you definitely want to be dumped in the VCD file
-> IO (Either String Text) |

Produce a four-state VCD (Value Change Dump) according to IEEE 1364-{1995,2001}. This function fails if a trace name contains either non-printable or non-VCD characters.

Due to lazy evaluation, the created VCD files might not contain all the traces you were expecting. You therefore have to provide a list of names you definately want to be dumped in the VCD file.

For example:

    vcd <- dumpVCD (0, 100) cntrOut ["main", "sub"]

Evaluates cntrOut long enough in order for to guarantee that the `main`, and `sub` traces end up in the generated VCD file.

# Replay functions

dumpReplayable Source #

Arguments

:: forall a (dom :: Domain). NFDataX a |
=> Int | Number of samples
-> Signal dom a | (One of) the outputs of the circuit containing the traces
-> String | Name of trace to dump
-> IO ByteString |

Dump a number of samples to a replayable bytestring.

replay :: forall a (dom :: Domain) (n :: Nat). (Typeable a, NFDataX a, BitPack a, KnownNat n, n ~ BitSize a) => ByteString -> Either String (Signal dom a) Source #

Take a serialized signal (dumped with `dumpReplayable`) and convert it back into a signal. Will error if dumped type does not match requested type. The first value in the signal that fails to decode will stop the decoding process and yield an error. Not that this always happens if you evaluate more values than were originally dumped.

# Internal

## Types

type Period = Int Source #

type Changed = Bool Source #

type Value = (Natural, Natural) Source #

type Width = Int Source #

type TraceMap = Map String (TypeRepBS, Period, Width, [Value]) Source #

type TypeRepBS = ByteString Source #

Serialized TypeRep we need to store for dumpReplayable / replay

## Functions

traceSignal# Source #

Arguments

:: forall (dom :: Domain) a. (BitPack a, NFDataX a, Typeable a) |
=> IORef TraceMap | Map to store the trace
-> Int | The associated clock period for the trace
-> String | Name of signal in the VCD output
-> Signal dom a | Signal to trace
-> IO (Signal dom a) |

Trace a single signal. Will emit an error if a signal with the same name was previously registered.

traceVecSignal# Source #

Arguments

:: forall (dom :: Domain) (n :: Nat) a. (KnownNat n, BitPack a, NFDataX a, Typeable a) |
=> IORef TraceMap | Map to store the traces
-> Int | Associated clock period for the trace
-> String | Name of signal in the VCD output. Will be appended by _0, _1, ..., _n.
-> Signal dom (Vec (n + 1) a) | Signal to trace
-> IO (Signal dom (Vec (n + 1) a)) |

Trace a single vector signal: each element in the vector will show up as a different trace. If the trace name already exists, this function will emit an error.

dumpVCD# Source #

Arguments

:: forall a (dom :: Domain). NFDataX a |
=> IORef TraceMap | Map with collected traces
-> (Int, Int) | (offset, number of samples)
-> Signal dom a | (One of) the output(s) the circuit containing the traces
-> [String] | The names of the traces you definitely want to be dumped to the VCD file
-> IO (Either String Text) |

Same as `dumpVCD`, but supplied with a custom tracemap

dumpVCD## Source #

Arguments

:: (Int, Int) | (offset, number of samples)
-> TraceMap |
-> UTCTime |
-> Either String Text |

Same as `dumpVCD`, but supplied with a custom tracemap and a custom timestamp

waitForTraces# Source #

Arguments

:: forall a (dom :: Domain). NFDataX a |
=> IORef TraceMap | Map with collected traces
-> Signal dom a | (One of) the output(s) the circuit containing the traces
-> [String] | The names of the traces you definitely want to be dumped to the VCD file
-> IO () |

Keep evaluating given signal until all trace names are present.

traceMap# :: IORef TraceMap Source #

Map of traces used by the non-internal trace and dumpvcd functions.