{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
module Clash.Signal.Trace
(
traceSignal1
, traceVecSignal1
, traceSignal
, traceVecSignal
, dumpVCD
, dumpReplayable
, replay
, VCDFile(..)
, VCDTime
, IDCode
, TimeUnit(..)
, DeclarationCommand(..)
, Var(..)
, SimulationCommand(..)
, ValueChange(..)
, Period
, Changed
, Value
, Width
, TraceMap
, TypeRepBS
, traceSignal#
, traceVecSignal#
, dumpVCD#
, dumpVCD0#
, dumpVCD1#
, waitForTraces#
, traceMap#
) where
import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Signal.Internal (fromList)
import Clash.Signal
(KnownDomain(..), SDomainConfiguration(..), Signal, bundle, unbundle)
import Clash.Sized.Vector (Vec, iterateI)
import qualified Clash.Sized.Vector as Vector
import Clash.Class.BitPack (BitPack, BitSize, pack, unpack)
import Clash.Promoted.Nat (snatToNum, SNat(..))
import Clash.Signal.Internal (Signal ((:-)), sample)
import Clash.XException (deepseqX, NFDataX)
import Clash.Sized.Internal.BitVector
(BitVector(BV))
import Control.Monad (foldM)
import Data.Bits (testBit)
import Data.Binary (encode, decodeOrFail)
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as ByteStringLazy
import Data.Char (ord, chr)
import Data.IORef
(IORef, atomicModifyIORef', atomicWriteIORef, newIORef, readIORef)
#if !MIN_VERSION_base(4,20,0)
import Data.List (foldl')
#endif
import Data.List (foldl1', unzip4, transpose, uncons)
import Data.List.Extra (snoc)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe, catMaybes)
import qualified Data.Text as Text
import Data.Time.Clock (UTCTime, getCurrentTime)
import Data.Time.Format (formatTime, defaultTimeLocale)
import GHC.Natural (Natural)
import GHC.Stack (HasCallStack)
import GHC.TypeLits (KnownNat, type (+))
import System.IO.Unsafe (unsafePerformIO)
import Type.Reflection (Typeable, TypeRep, typeRep)
#ifdef CABAL
import qualified Data.Version
import qualified Paths_clash_prelude
#endif
type Period = Int
type Changed = Bool
type Value = (Natural, Natural)
type Width = Int
type TypeRepBS = ByteString
type TraceMap = Map.Map String (TypeRepBS, Period, Width, [Value])
traceMap# :: IORef TraceMap
traceMap# :: IORef TraceMap
traceMap# = IO (IORef TraceMap) -> IORef TraceMap
forall a. IO a -> a
unsafePerformIO (TraceMap -> IO (IORef TraceMap)
forall a. a -> IO (IORef a)
newIORef TraceMap
forall k a. Map k a
Map.empty)
{-# CLASH_OPAQUE traceMap# #-}
mkTrace
:: HasCallStack
=> BitPack a
=> NFDataX a
=> Signal dom a
-> [Value]
mkTrace :: forall a (dom :: Domain).
(HasCallStack, BitPack a, NFDataX a) =>
Signal dom a -> [Value]
mkTrace Signal dom a
signal = Signal dom Value -> [Value]
forall (f :: Type -> Type) a. (Foldable f, NFDataX a) => f a -> [a]
sample (BitVector (BitSize a) -> Value
forall {n :: Natural}. BitVector n -> Value
unsafeToTup (BitVector (BitSize a) -> Value)
-> (a -> BitVector (BitSize a)) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack (a -> Value) -> Signal dom a -> Signal dom Value
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom a
signal)
where
unsafeToTup :: BitVector n -> Value
unsafeToTup (BV Natural
mask Natural
value) = (Natural
mask, Natural
value)
traceSignal#
:: forall dom a
. ( BitPack a
, NFDataX a
, Typeable a )
=> IORef TraceMap
-> Int
-> String
-> Signal dom a
-> IO (Signal dom a)
traceSignal# :: forall (dom :: Domain) a.
(BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
traceSignal# IORef TraceMap
traceMap Int
period [Char]
traceName Signal dom a
signal =
IORef TraceMap
-> (TraceMap -> (TraceMap, Signal dom a)) -> IO (Signal dom a)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef TraceMap
traceMap ((TraceMap -> (TraceMap, Signal dom a)) -> IO (Signal dom a))
-> (TraceMap -> (TraceMap, Signal dom a)) -> IO (Signal dom a)
forall a b. (a -> b) -> a -> b
$ \TraceMap
m ->
if [Char] -> TraceMap -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member [Char]
traceName TraceMap
m then
[Char] -> (TraceMap, Signal dom a)
forall a. HasCallStack => [Char] -> a
error ([Char] -> (TraceMap, Signal dom a))
-> [Char] -> (TraceMap, Signal dom a)
forall a b. (a -> b) -> a -> b
$ [Char]
"Already tracing a signal with the name: '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
traceName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'."
else
( [Char] -> (TypeRepBS, Int, Int, [Value]) -> TraceMap -> TraceMap
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert
[Char]
traceName
( TypeRep a -> TypeRepBS
forall a. Binary a => a -> TypeRepBS
encode (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a)
, Int
period
, Int
width
, Signal dom a -> [Value]
forall a (dom :: Domain).
(HasCallStack, BitPack a, NFDataX a) =>
Signal dom a -> [Value]
mkTrace Signal dom a
signal)
TraceMap
m
, Signal dom a
signal)
where
width :: Int
width = SNat (BitSize a) -> Int
forall a (n :: Natural). Num a => SNat n -> a
snatToNum (forall (n :: Natural). KnownNat n => SNat n
SNat @(BitSize a))
{-# CLASH_OPAQUE traceSignal# #-}
traceVecSignal#
:: forall dom n 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))
traceVecSignal# :: forall (dom :: Domain) (n :: Natural) a.
(KnownNat n, BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int
-> [Char]
-> Signal dom (Vec (n + 1) a)
-> IO (Signal dom (Vec (n + 1) a))
traceVecSignal# IORef TraceMap
traceMap Int
period [Char]
vecTraceName (Signal dom (Vec (n + 1) a) -> Unbundled dom (Vec (n + 1) a)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
forall (dom :: Domain).
Signal dom (Vec (n + 1) a) -> Unbundled dom (Vec (n + 1) a)
unbundle -> Unbundled dom (Vec (n + 1) a)
vecSignal) =
(Vec (n + 1) (Signal dom a) -> Signal dom (Vec (n + 1) a))
-> IO (Vec (n + 1) (Signal dom a))
-> IO (Signal dom (Vec (n + 1) a))
forall a b. (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Vec (n + 1) (Signal dom a) -> Signal dom (Vec (n + 1) a)
Unbundled dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
forall a (dom :: Domain).
Bundle a =>
Unbundled dom a -> Signal dom a
forall (dom :: Domain).
Unbundled dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
bundle (IO (Vec (n + 1) (Signal dom a))
-> IO (Signal dom (Vec (n + 1) a)))
-> (Vec (n + 1) (IO (Signal dom a))
-> IO (Vec (n + 1) (Signal dom a)))
-> Vec (n + 1) (IO (Signal dom a))
-> IO (Signal dom (Vec (n + 1) a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vec (n + 1) (IO (Signal dom a)) -> IO (Vec (n + 1) (Signal dom a))
forall (t :: Type -> Type) (f :: Type -> Type) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: Type -> Type) a.
Applicative f =>
Vec (n + 1) (f a) -> f (Vec (n + 1) a)
sequenceA (Vec (n + 1) (IO (Signal dom a))
-> IO (Signal dom (Vec (n + 1) a)))
-> Vec (n + 1) (IO (Signal dom a))
-> IO (Signal dom (Vec (n + 1) a))
forall a b. (a -> b) -> a -> b
$
(Int -> Signal dom a -> IO (Signal dom a))
-> Vec (n + 1) Int
-> Vec (n + 1) (Signal dom a)
-> Vec (n + 1) (IO (Signal dom a))
forall a b c (n :: Natural).
(a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
Vector.zipWith Int -> Signal dom a -> IO (Signal dom a)
trace' ((Int -> Int) -> Int -> Vec (n + 1) Int
forall (n :: Natural) a. KnownNat n => (a -> a) -> a -> Vec n a
iterateI Int -> Int
forall a. Enum a => a -> a
succ (Int
0 :: Int)) Vec (n + 1) (Signal dom a)
Unbundled dom (Vec (n + 1) a)
vecSignal
where
trace' :: Int -> Signal dom a -> IO (Signal dom a)
trace' Int
i Signal dom a
s = IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
forall (dom :: Domain) a.
(BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
traceSignal# IORef TraceMap
traceMap Int
period (Int -> [Char]
name' Int
i) Signal dom a
s
name' :: Int -> [Char]
name' Int
i = [Char]
vecTraceName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"_" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
{-# CLASH_OPAQUE traceVecSignal# #-}
traceSignal
:: forall dom a
. ( KnownDomain dom
, BitPack a
, NFDataX a
, Typeable a )
=> String
-> Signal dom a
-> Signal dom a
traceSignal :: forall (dom :: Domain) a.
(KnownDomain dom, BitPack a, NFDataX a, Typeable a) =>
[Char] -> Signal dom a -> Signal dom a
traceSignal [Char]
traceName Signal dom a
signal =
case forall (dom :: Domain).
KnownDomain dom =>
SDomainConfiguration dom (KnownConf dom)
knownDomain @dom of
SDomainConfiguration{SNat period
sPeriod :: SNat period
sPeriod :: forall (dom :: Domain) (period :: Natural) (edge :: ActiveEdge)
(reset :: ResetKind) (init :: InitBehavior)
(polarity :: ResetPolarity).
SDomainConfiguration
dom ('DomainConfiguration dom period edge reset init polarity)
-> SNat period
sPeriod} ->
IO (Signal dom a) -> Signal dom a
forall a. IO a -> a
unsafePerformIO (IO (Signal dom a) -> Signal dom a)
-> IO (Signal dom a) -> Signal dom a
forall a b. (a -> b) -> a -> b
$
IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
forall (dom :: Domain) a.
(BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
traceSignal# IORef TraceMap
traceMap# (SNat period -> Int
forall a (n :: Natural). Num a => SNat n -> a
snatToNum SNat period
sPeriod) [Char]
traceName Signal dom a
signal
{-# CLASH_OPAQUE traceSignal #-}
{-# ANN traceSignal hasBlackBox #-}
traceSignal1
:: ( BitPack a
, NFDataX a
, Typeable a )
=> String
-> Signal dom a
-> Signal dom a
traceSignal1 :: forall a (dom :: Domain).
(BitPack a, NFDataX a, Typeable a) =>
[Char] -> Signal dom a -> Signal dom a
traceSignal1 [Char]
traceName Signal dom a
signal =
IO (Signal dom a) -> Signal dom a
forall a. IO a -> a
unsafePerformIO (IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
forall (dom :: Domain) a.
(BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int -> [Char] -> Signal dom a -> IO (Signal dom a)
traceSignal# IORef TraceMap
traceMap# Int
1 [Char]
traceName Signal dom a
signal)
{-# CLASH_OPAQUE traceSignal1 #-}
{-# ANN traceSignal1 hasBlackBox #-}
traceVecSignal
:: forall dom a n
. ( KnownDomain dom
, KnownNat n
, BitPack a
, NFDataX a
, Typeable a )
=> String
-> Signal dom (Vec (n+1) a)
-> Signal dom (Vec (n+1) a)
traceVecSignal :: forall (dom :: Domain) a (n :: Natural).
(KnownDomain dom, KnownNat n, BitPack a, NFDataX a, Typeable a) =>
[Char] -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
traceVecSignal [Char]
traceName Signal dom (Vec (n + 1) a)
signal =
case forall (dom :: Domain).
KnownDomain dom =>
SDomainConfiguration dom (KnownConf dom)
knownDomain @dom of
SDomainConfiguration{SNat period
sPeriod :: forall (dom :: Domain) (period :: Natural) (edge :: ActiveEdge)
(reset :: ResetKind) (init :: InitBehavior)
(polarity :: ResetPolarity).
SDomainConfiguration
dom ('DomainConfiguration dom period edge reset init polarity)
-> SNat period
sPeriod :: SNat period
sPeriod} ->
IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a)
forall a. IO a -> a
unsafePerformIO (IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a))
-> IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a)
forall a b. (a -> b) -> a -> b
$
IORef TraceMap
-> Int
-> [Char]
-> Signal dom (Vec (n + 1) a)
-> IO (Signal dom (Vec (n + 1) a))
forall (dom :: Domain) (n :: Natural) a.
(KnownNat n, BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int
-> [Char]
-> Signal dom (Vec (n + 1) a)
-> IO (Signal dom (Vec (n + 1) a))
traceVecSignal# IORef TraceMap
traceMap# (SNat period -> Int
forall a (n :: Natural). Num a => SNat n -> a
snatToNum SNat period
sPeriod) [Char]
traceName Signal dom (Vec (n + 1) a)
signal
{-# CLASH_OPAQUE traceVecSignal #-}
{-# ANN traceVecSignal hasBlackBox #-}
traceVecSignal1
:: ( KnownNat n
, BitPack a
, NFDataX a
, Typeable a )
=> String
-> Signal dom (Vec (n+1) a)
-> Signal dom (Vec (n+1) a)
traceVecSignal1 :: forall (n :: Natural) a (dom :: Domain).
(KnownNat n, BitPack a, NFDataX a, Typeable a) =>
[Char] -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
traceVecSignal1 [Char]
traceName Signal dom (Vec (n + 1) a)
signal =
IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a)
forall a. IO a -> a
unsafePerformIO (IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a))
-> IO (Signal dom (Vec (n + 1) a)) -> Signal dom (Vec (n + 1) a)
forall a b. (a -> b) -> a -> b
$ IORef TraceMap
-> Int
-> [Char]
-> Signal dom (Vec (n + 1) a)
-> IO (Signal dom (Vec (n + 1) a))
forall (dom :: Domain) (n :: Natural) a.
(KnownNat n, BitPack a, NFDataX a, Typeable a) =>
IORef TraceMap
-> Int
-> [Char]
-> Signal dom (Vec (n + 1) a)
-> IO (Signal dom (Vec (n + 1) a))
traceVecSignal# IORef TraceMap
traceMap# Int
1 [Char]
traceName Signal dom (Vec (n + 1) a)
signal
{-# CLASH_OPAQUE traceVecSignal1 #-}
{-# ANN traceVecSignal1 hasBlackBox #-}
data VCDFile = VCDFile [DeclarationCommand] [SimulationCommand]
deriving (Int -> VCDFile -> [Char] -> [Char]
[VCDFile] -> [Char] -> [Char]
VCDFile -> [Char]
(Int -> VCDFile -> [Char] -> [Char])
-> (VCDFile -> [Char])
-> ([VCDFile] -> [Char] -> [Char])
-> Show VCDFile
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> VCDFile -> [Char] -> [Char]
showsPrec :: Int -> VCDFile -> [Char] -> [Char]
$cshow :: VCDFile -> [Char]
show :: VCDFile -> [Char]
$cshowList :: [VCDFile] -> [Char] -> [Char]
showList :: [VCDFile] -> [Char] -> [Char]
Show)
type VCDTime = Int
type IDCode = String
data TimeUnit = S | MS | US | NS | PS | FS
instance Show TimeUnit where
showsPrec :: Int -> TimeUnit -> [Char] -> [Char]
showsPrec Int
_ TimeUnit
S = (Char
's' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:)
showsPrec Int
_ TimeUnit
MS = [Char] -> [Char] -> [Char]
showString [Char]
"ms"
showsPrec Int
_ TimeUnit
US = [Char] -> [Char] -> [Char]
showString [Char]
"us"
showsPrec Int
_ TimeUnit
NS = [Char] -> [Char] -> [Char]
showString [Char]
"ns"
showsPrec Int
_ TimeUnit
PS = [Char] -> [Char] -> [Char]
showString [Char]
"ps"
showsPrec Int
_ TimeUnit
FS = [Char] -> [Char] -> [Char]
showString [Char]
"fs"
data DeclarationCommand
= TimeScale VCDTime TimeUnit
| Vars [Var]
deriving (Int -> DeclarationCommand -> [Char] -> [Char]
[DeclarationCommand] -> [Char] -> [Char]
DeclarationCommand -> [Char]
(Int -> DeclarationCommand -> [Char] -> [Char])
-> (DeclarationCommand -> [Char])
-> ([DeclarationCommand] -> [Char] -> [Char])
-> Show DeclarationCommand
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> DeclarationCommand -> [Char] -> [Char]
showsPrec :: Int -> DeclarationCommand -> [Char] -> [Char]
$cshow :: DeclarationCommand -> [Char]
show :: DeclarationCommand -> [Char]
$cshowList :: [DeclarationCommand] -> [Char] -> [Char]
showList :: [DeclarationCommand] -> [Char] -> [Char]
Show)
data Var
= Var
{ Var -> Int
varSize :: Width
, Var -> [Char]
varIDCode :: IDCode
, Var -> [Char]
varReference :: String
}
deriving (Int -> Var -> [Char] -> [Char]
[Var] -> [Char] -> [Char]
Var -> [Char]
(Int -> Var -> [Char] -> [Char])
-> (Var -> [Char]) -> ([Var] -> [Char] -> [Char]) -> Show Var
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> Var -> [Char] -> [Char]
showsPrec :: Int -> Var -> [Char] -> [Char]
$cshow :: Var -> [Char]
show :: Var -> [Char]
$cshowList :: [Var] -> [Char] -> [Char]
showList :: [Var] -> [Char] -> [Char]
Show)
data SimulationCommand
= DumpVars [ValueChange]
| SimulationTime VCDTime
| SimulationValueChange ValueChange
deriving (Int -> SimulationCommand -> [Char] -> [Char]
[SimulationCommand] -> [Char] -> [Char]
SimulationCommand -> [Char]
(Int -> SimulationCommand -> [Char] -> [Char])
-> (SimulationCommand -> [Char])
-> ([SimulationCommand] -> [Char] -> [Char])
-> Show SimulationCommand
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SimulationCommand -> [Char] -> [Char]
showsPrec :: Int -> SimulationCommand -> [Char] -> [Char]
$cshow :: SimulationCommand -> [Char]
show :: SimulationCommand -> [Char]
$cshowList :: [SimulationCommand] -> [Char] -> [Char]
showList :: [SimulationCommand] -> [Char] -> [Char]
Show, SimulationCommand -> SimulationCommand -> Bool
(SimulationCommand -> SimulationCommand -> Bool)
-> (SimulationCommand -> SimulationCommand -> Bool)
-> Eq SimulationCommand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SimulationCommand -> SimulationCommand -> Bool
== :: SimulationCommand -> SimulationCommand -> Bool
$c/= :: SimulationCommand -> SimulationCommand -> Bool
/= :: SimulationCommand -> SimulationCommand -> Bool
Eq)
data ValueChange
= ValueChange
{ ValueChange -> Int
changeSize :: Width
, ValueChange -> [Char]
changeIDCode :: IDCode
, ValueChange -> Value
changeValue :: Value
}
deriving (Int -> ValueChange -> [Char] -> [Char]
[ValueChange] -> [Char] -> [Char]
ValueChange -> [Char]
(Int -> ValueChange -> [Char] -> [Char])
-> (ValueChange -> [Char])
-> ([ValueChange] -> [Char] -> [Char])
-> Show ValueChange
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ValueChange -> [Char] -> [Char]
showsPrec :: Int -> ValueChange -> [Char] -> [Char]
$cshow :: ValueChange -> [Char]
show :: ValueChange -> [Char]
$cshowList :: [ValueChange] -> [Char] -> [Char]
showList :: [ValueChange] -> [Char] -> [Char]
Show, ValueChange -> ValueChange -> Bool
(ValueChange -> ValueChange -> Bool)
-> (ValueChange -> ValueChange -> Bool) -> Eq ValueChange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ValueChange -> ValueChange -> Bool
== :: ValueChange -> ValueChange -> Bool
$c/= :: ValueChange -> ValueChange -> Bool
/= :: ValueChange -> ValueChange -> Bool
Eq)
iso8601Format :: UTCTime -> String
iso8601Format :: UTCTime -> [Char]
iso8601Format = TimeLocale -> [Char] -> UTCTime -> [Char]
forall t. FormatTime t => TimeLocale -> [Char] -> t -> [Char]
formatTime TimeLocale
defaultTimeLocale [Char]
"%Y-%m-%dT%H:%M:%S"
toPeriodMap :: TraceMap -> Map.Map Period [(String, Width, [Value])]
toPeriodMap :: TraceMap -> Map Int [([Char], Int, [Value])]
toPeriodMap TraceMap
m = (Map Int [([Char], Int, [Value])]
-> ([Char], (TypeRepBS, Int, Int, [Value]))
-> Map Int [([Char], Int, [Value])])
-> Map Int [([Char], Int, [Value])]
-> [([Char], (TypeRepBS, Int, Int, [Value]))]
-> Map Int [([Char], Int, [Value])]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Map Int [([Char], Int, [Value])]
-> ([Char], (TypeRepBS, Int, Int, [Value]))
-> Map Int [([Char], Int, [Value])]
forall {k} {a} {b} {c} {a}.
Ord k =>
Map k [(a, b, c)] -> (a, (a, k, b, c)) -> Map k [(a, b, c)]
go Map Int [([Char], Int, [Value])]
forall k a. Map k a
Map.empty (TraceMap -> [([Char], (TypeRepBS, Int, Int, [Value]))]
forall k a. Map k a -> [(k, a)]
Map.assocs TraceMap
m)
where
go :: Map k [(a, b, c)] -> (a, (a, k, b, c)) -> Map k [(a, b, c)]
go Map k [(a, b, c)]
periodMap (a
traceName, (a
_rep, k
period, b
width, c
values)) =
(Maybe [(a, b, c)] -> Maybe [(a, b, c)])
-> k -> Map k [(a, b, c)] -> Map k [(a, b, c)]
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter ([(a, b, c)] -> Maybe [(a, b, c)]
forall a. a -> Maybe a
Just ([(a, b, c)] -> Maybe [(a, b, c)])
-> (Maybe [(a, b, c)] -> [(a, b, c)])
-> Maybe [(a, b, c)]
-> Maybe [(a, b, c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe [(a, b, c)] -> [(a, b, c)]
go') k
period Map k [(a, b, c)]
periodMap
where
go' :: Maybe [(a, b, c)] -> [(a, b, c)]
go' = ((a
traceName, b
width, c
values)(a, b, c) -> [(a, b, c)] -> [(a, b, c)]
forall a. a -> [a] -> [a]
:) ([(a, b, c)] -> [(a, b, c)])
-> (Maybe [(a, b, c)] -> [(a, b, c)])
-> Maybe [(a, b, c)]
-> [(a, b, c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(a, b, c)] -> Maybe [(a, b, c)] -> [(a, b, c)]
forall a. a -> Maybe a -> a
fromMaybe [])
flattenMap :: Map.Map a [b] -> [(a, b)]
flattenMap :: forall a b. Map a [b] -> [(a, b)]
flattenMap Map a [b]
m = [[(a, b)]] -> [(a, b)]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [[(a
a, b
b) | b
b <- [b]
bs] | (a
a, [b]
bs) <- Map a [b] -> [(a, [b])]
forall k a. Map k a -> [(k, a)]
Map.assocs Map a [b]
m]
printable :: Char -> Bool
printable :: Char -> Bool
printable (Char -> Int
ord -> Int
c) = Int
33 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
c Bool -> Bool -> Bool
&& Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
126
dumpVCD1#
:: (Int, Int)
-> TraceMap
-> Either String VCDFile
dumpVCD1# :: (Int, Int) -> TraceMap -> Either [Char] VCDFile
dumpVCD1# (Int
offset, Int
cycles) TraceMap
traceMap
| Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
[Char] -> Either [Char] VCDFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> Either [Char] VCDFile)
-> [Char] -> Either [Char] VCDFile
forall a b. (a -> b) -> a -> b
$ [Char]
"dumpVCD: offset was " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
offset [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", but cannot be negative."
| Int
cycles Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
[Char] -> Either [Char] VCDFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> Either [Char] VCDFile)
-> [Char] -> Either [Char] VCDFile
forall a b. (a -> b) -> a -> b
$ [Char]
"dumpVCD: cycles was " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
cycles [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", but cannot be negative."
| TraceMap -> Bool
forall a. Map [Char] a -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null TraceMap
traceMap =
[Char] -> Either [Char] VCDFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> Either [Char] VCDFile)
-> [Char] -> Either [Char] VCDFile
forall a b. (a -> b) -> a -> b
$ [Char]
"dumpVCD: no traces found. Extend the given trace names."
| ([Char]
nm:[[Char]]
_) <- [[Char]]
offensiveNames =
[Char] -> Either [Char] VCDFile
forall a b. a -> Either a b
Left ([Char] -> Either [Char] VCDFile)
-> [Char] -> Either [Char] VCDFile
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords [ [Char]
"Trace '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
nm [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"' contains"
, [Char]
"non-printable ASCII characters, which is not"
, [Char]
"supported by VCD." ]
| Bool
otherwise =
VCDFile -> Either [Char] VCDFile
forall a b. b -> Either a b
Right
( [DeclarationCommand] -> [SimulationCommand] -> VCDFile
VCDFile
[ Int -> TimeUnit -> DeclarationCommand
TimeScale Int
timescale TimeUnit
PS
, [Var] -> DeclarationCommand
Vars [Int -> [Char] -> [Char] -> Var
Var Int
w [Char]
l [Char]
n | (Int
w, [Char]
l, [Char]
n) <- [Int] -> [[Char]] -> [[Char]] -> [(Int, [Char], [Char])]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Int]
widths [[Char]]
labels [[Char]]
traceNames]
]
( [ Int -> SimulationCommand
SimulationTime Int
0
, [ValueChange] -> SimulationCommand
DumpVars [ValueChange]
initValues
]
[SimulationCommand] -> [SimulationCommand] -> [SimulationCommand]
forall a. [a] -> [a] -> [a]
++ [[SimulationCommand]] -> [SimulationCommand]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat ([Maybe [SimulationCommand]] -> [[SimulationCommand]]
forall a. [Maybe a] -> [a]
catMaybes [Maybe [SimulationCommand]]
bodyParts)
)
)
where
offensiveNames :: [[Char]]
offensiveNames = ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Char -> Bool) -> [Char] -> Bool
forall (t :: Type -> Type) a.
Foldable t =>
(a -> Bool) -> t a -> Bool
any (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
printable)) [[Char]]
traceNames
labels :: [[Char]]
labels = ([Char] -> [[Char]]) -> [[Char]] -> [[Char]]
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> [b]) -> t a -> [b]
concatMap (\[Char]
s -> (Char -> [Char]) -> [Char] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> Char -> [Char]
forall a. [a] -> a -> [a]
snoc [Char]
s) [Char]
alphabet) ([][Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
labels)
where
alphabet :: [Char]
alphabet = (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
chr [Int
33..Int
126]
timescale :: Int
timescale = (Int -> Int -> Int) -> [Int] -> Int
forall a. HasCallStack => (a -> a -> a) -> [a] -> a
foldl1' Int -> Int -> Int
forall a. Integral a => a -> a -> a
gcd (Map Int [([Char], Int, [Value])] -> [Int]
forall k a. Map k a -> [k]
Map.keys Map Int [([Char], Int, [Value])]
periodMap)
periodMap :: Map Int [([Char], Int, [Value])]
periodMap = TraceMap -> Map Int [([Char], Int, [Value])]
toPeriodMap TraceMap
traceMap
([Int]
periods, [[Char]]
traceNames, [Int]
widths, [[Value]]
valuess) =
[(Int, [Char], Int, [Value])]
-> ([Int], [[Char]], [Int], [[Value]])
forall a b c d. [(a, b, c, d)] -> ([a], [b], [c], [d])
unzip4 ([(Int, [Char], Int, [Value])]
-> ([Int], [[Char]], [Int], [[Value]]))
-> [(Int, [Char], Int, [Value])]
-> ([Int], [[Char]], [Int], [[Value]])
forall a b. (a -> b) -> a -> b
$ ((Int, ([Char], Int, [Value])) -> (Int, [Char], Int, [Value]))
-> [(Int, ([Char], Int, [Value]))] -> [(Int, [Char], Int, [Value])]
forall a b. (a -> b) -> [a] -> [b]
map
(\(Int
a, ([Char]
b, Int
c, [Value]
d)) -> (Int
a, [Char]
b, Int
c, [Value]
d))
(Map Int [([Char], Int, [Value])] -> [(Int, ([Char], Int, [Value]))]
forall a b. Map a [b] -> [(a, b)]
flattenMap Map Int [([Char], Int, [Value])]
periodMap)
periods' :: [Int]
periods' = (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
timescale) [Int]
periods
valuess' :: [[Value]]
valuess' = ([Value] -> [Value]) -> [[Value]] -> [[Value]]
forall a b. (a -> b) -> [a] -> [b]
map [Value] -> [Value]
slice ([[Value]] -> [[Value]]) -> [[Value]] -> [[Value]]
forall a b. (a -> b) -> a -> b
$ (Int -> [Value] -> [Value]) -> [Int] -> [[Value]] -> [[Value]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> [Value] -> [Value]
forall {a}. Int -> [a] -> [a]
normalize [Int]
periods' [[Value]]
valuess
normalize :: Int -> [a] -> [a]
normalize Int
period (a
initial:[a]
values) = a
initial a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> [a]) -> [a] -> [a]
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> [b]) -> t a -> [b]
concatMap (Int -> a -> [a]
forall a. Int -> a -> [a]
replicate Int
period) [a]
values
normalize Int
_ [] = []
slice :: [Value] -> [Value]
slice [Value]
values = Int -> [Value] -> [Value]
forall {a}. Int -> [a] -> [a]
drop Int
offset ([Value] -> [Value]) -> [Value] -> [Value]
forall a b. (a -> b) -> a -> b
$ Int -> [Value] -> [Value]
forall {a}. Int -> [a] -> [a]
take Int
cycles [Value]
values
initValues :: [ValueChange]
initValues = ((Value -> ValueChange) -> Value -> ValueChange)
-> [Value -> ValueChange] -> [Value] -> [ValueChange]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Value -> ValueChange) -> Value -> ValueChange
forall a b. (a -> b) -> a -> b
($) [Value -> ValueChange]
formatters [Value]
inits
formatters :: [Value -> ValueChange]
formatters = (Int -> [Char] -> Value -> ValueChange)
-> [Int] -> [[Char]] -> [Value -> ValueChange]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> [Char] -> Value -> ValueChange
ValueChange [Int]
widths [[Char]]
labels
inits :: [Value]
inits = ([Value] -> Value) -> [[Value]] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (Value
-> ((Value, [Value]) -> Value) -> Maybe (Value, [Value]) -> Value
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([Char] -> Value
forall a. HasCallStack => [Char] -> a
error [Char]
"dumpVCD##: empty value") (Value, [Value]) -> Value
forall a b. (a, b) -> a
fst (Maybe (Value, [Value]) -> Value)
-> ([Value] -> Maybe (Value, [Value])) -> [Value] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Value] -> Maybe (Value, [Value])
forall a. [a] -> Maybe (a, [a])
uncons) [[Value]]
valuess'
tails :: [[(Bool, Value)]]
tails = ([Value] -> [(Bool, Value)]) -> [[Value]] -> [[(Bool, Value)]]
forall a b. (a -> b) -> [a] -> [b]
map [Value] -> [(Bool, Value)]
changed [[Value]]
valuess'
changed :: [Value] -> [(Changed, Value)]
changed :: [Value] -> [(Bool, Value)]
changed (Value
s:[Value]
ss) = [Bool] -> [Value] -> [(Bool, Value)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((Value -> Value -> Bool) -> [Value] -> [Value] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (Value
sValue -> [Value] -> [Value]
forall a. a -> [a] -> [a]
:[Value]
ss) [Value]
ss) [Value]
ss
changed [] = []
bodyParts :: [Maybe [SimulationCommand]]
bodyParts :: [Maybe [SimulationCommand]]
bodyParts = (Int -> Maybe [SimulationCommand] -> Maybe [SimulationCommand])
-> [Int]
-> [Maybe [SimulationCommand]]
-> [Maybe [SimulationCommand]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Maybe [SimulationCommand] -> Maybe [SimulationCommand]
go [Int
0 ..] (([(Bool, Value)] -> Maybe [SimulationCommand])
-> [[(Bool, Value)]] -> [Maybe [SimulationCommand]]
forall a b. (a -> b) -> [a] -> [b]
map [(Bool, Value)] -> Maybe [SimulationCommand]
bodyPart ([[(Bool, Value)]] -> [[(Bool, Value)]]
forall a. [[a]] -> [[a]]
Data.List.transpose [[(Bool, Value)]]
tails))
where
go :: VCDTime -> Maybe [SimulationCommand] -> Maybe [SimulationCommand]
go :: Int -> Maybe [SimulationCommand] -> Maybe [SimulationCommand]
go Int
t Maybe [SimulationCommand]
vc = ([SimulationCommand] -> [SimulationCommand])
-> Maybe [SimulationCommand] -> Maybe [SimulationCommand]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> SimulationCommand
SimulationTime Int
t SimulationCommand -> [SimulationCommand] -> [SimulationCommand]
forall a. a -> [a] -> [a]
:) Maybe [SimulationCommand]
vc
bodyPart :: [(Changed, Value)] -> Maybe [SimulationCommand]
bodyPart :: [(Bool, Value)] -> Maybe [SimulationCommand]
bodyPart [(Bool, Value)]
values =
let
formatted :: [(Bool, SimulationCommand)]
formatted = [(Bool
c, ValueChange -> SimulationCommand
SimulationValueChange (Value -> ValueChange
f Value
v)) | (Value -> ValueChange
f, (Bool
c, Value
v)) <- [Value -> ValueChange]
-> [(Bool, Value)] -> [(Value -> ValueChange, (Bool, Value))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Value -> ValueChange]
formatters [(Bool, Value)]
values]
formatted' :: [SimulationCommand]
formatted' = ((Bool, SimulationCommand) -> SimulationCommand)
-> [(Bool, SimulationCommand)] -> [SimulationCommand]
forall a b. (a -> b) -> [a] -> [b]
map (Bool, SimulationCommand) -> SimulationCommand
forall a b. (a, b) -> b
snd ([(Bool, SimulationCommand)] -> [SimulationCommand])
-> [(Bool, SimulationCommand)] -> [SimulationCommand]
forall a b. (a -> b) -> a -> b
$ ((Bool, SimulationCommand) -> Bool)
-> [(Bool, SimulationCommand)] -> [(Bool, SimulationCommand)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool, SimulationCommand) -> Bool
forall a b. (a, b) -> a
fst ([(Bool, SimulationCommand)] -> [(Bool, SimulationCommand)])
-> [(Bool, SimulationCommand)] -> [(Bool, SimulationCommand)]
forall a b. (a -> b) -> a -> b
$ [(Bool, SimulationCommand)]
formatted
in
if [SimulationCommand] -> Bool
forall a. [a] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [SimulationCommand]
formatted' then Maybe [SimulationCommand]
forall a. Maybe a
Nothing else [SimulationCommand] -> Maybe [SimulationCommand]
forall a. a -> Maybe a
Just [SimulationCommand]
formatted'
dumpVCD0#
:: (Int, Int)
-> TraceMap
-> UTCTime
-> Either String Text.Text
dumpVCD0# :: (Int, Int) -> TraceMap -> UTCTime -> Either [Char] Text
dumpVCD0# (Int, Int)
slice TraceMap
traceMap UTCTime
now =
(VCDFile -> Text) -> Either [Char] VCDFile -> Either [Char] Text
forall a b. (a -> b) -> Either [Char] a -> Either [Char] b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap VCDFile -> Text
renderVCD ((Int, Int) -> TraceMap -> Either [Char] VCDFile
dumpVCD1# (Int, Int)
slice TraceMap
traceMap)
where
renderVCD :: VCDFile -> Text
renderVCD (VCDFile [DeclarationCommand]
decCmds [SimulationCommand]
simCmds) =
[Text] -> Text
Text.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
[ [Text] -> Text
Text.unwords [Text]
headerDate
, [Text] -> Text
Text.unwords [Text]
headerVersion
, [Text] -> Text
Text.unwords [Text]
headerComment
]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [DeclarationCommand] -> [Text]
renderDecCmds [DeclarationCommand]
decCmds
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Text
"$enddefinitions $end"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [SimulationCommand] -> [Text]
renderSimCmds [SimulationCommand]
simCmds
renderDecCmds :: [DeclarationCommand] -> [Text]
renderDecCmds [] = []
renderDecCmds ((TimeScale Int
s TimeUnit
u) : [DeclarationCommand]
cmds) =
[ [Text] -> Text
Text.unwords
[ Text
"$timescale"
, [Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
forall a. Show a => a -> [Char] -> [Char]
shows Int
s ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ TimeUnit -> [Char]
forall a. Show a => a -> [Char]
show TimeUnit
u
, Text
"$end"
]
]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [DeclarationCommand] -> [Text]
renderDecCmds [DeclarationCommand]
cmds
renderDecCmds ((Vars [Var]
vs) : [DeclarationCommand]
cmds) =
[ Text
"$scope module logic $end"
, Text -> [Text] -> Text
Text.intercalate Text
"\n" ((Var -> Text) -> [Var] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Var -> Text
renderVar [Var]
vs)
, Text
"$upscope $end"
]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [DeclarationCommand] -> [Text]
renderDecCmds [DeclarationCommand]
cmds
renderVar :: Var -> Text
renderVar Var{Int
[Char]
varSize :: Var -> Int
varIDCode :: Var -> [Char]
varReference :: Var -> [Char]
varSize :: Int
varIDCode :: [Char]
varReference :: [Char]
..} =
([Text] -> Text
Text.unwords ([Text] -> Text) -> ([[Char]] -> [Text]) -> [[Char]] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Text) -> [[Char]] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Text
Text.pack)
[ [Char]
"$var wire"
, Int -> [Char]
forall a. Show a => a -> [Char]
show Int
varSize
, [Char]
varIDCode
, [Char]
varReference
, [Char]
"$end"
]
renderSimCmds :: [SimulationCommand] -> [Text]
renderSimCmds [] = []
renderSimCmds ((DumpVars [ValueChange]
vars) : [SimulationCommand]
cmds) =
Text
"$dumpvars"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (ValueChange -> Text) -> [ValueChange] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ValueChange -> Text
renderValueChange [ValueChange]
vars
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Text
"$end"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [SimulationCommand] -> [Text]
renderSimCmds [SimulationCommand]
cmds
renderSimCmds ((SimulationTime Int
t) : [SimulationCommand]
cmds) =
[Char] -> Text
Text.pack (Char
'#' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char]
forall a. Show a => a -> [Char]
show Int
t) Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [SimulationCommand] -> [Text]
renderSimCmds [SimulationCommand]
cmds
renderSimCmds ((SimulationValueChange ValueChange
vc) : [SimulationCommand]
cmds) =
ValueChange -> Text
renderValueChange ValueChange
vc Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [SimulationCommand] -> [Text]
renderSimCmds [SimulationCommand]
cmds
renderValueChange :: ValueChange -> Text
renderValueChange (ValueChange Int
1 [Char]
idCode (Natural
0, Natural
0)) =
[Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Char
'0' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
idCode
renderValueChange (ValueChange Int
1 [Char]
idCode (Natural
0, Natural
1)) =
[Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Char
'1' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
idCode
renderValueChange (ValueChange Int
1 [Char]
idCode (Natural
1, Natural
_)) =
[Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Char
'x' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
idCode
renderValueChange (ValueChange Int
1 [Char]
idCode (Natural
mask, Natural
val)) =
[Char] -> Text
forall a. HasCallStack => [Char] -> a
error ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$
[Char]
"Can't format 1 bit wide value for "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
forall a. Show a => a -> [Char]
show [Char]
idCode
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": value "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Natural -> [Char]
forall a. Show a => a -> [Char]
show Natural
val
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" and mask "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Natural -> [Char]
forall a. Show a => a -> [Char]
show Natural
mask
renderValueChange ValueChange{Int
[Char]
Value
changeSize :: ValueChange -> Int
changeIDCode :: ValueChange -> [Char]
changeValue :: ValueChange -> Value
changeSize :: Int
changeIDCode :: [Char]
changeValue :: Value
..} =
[Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Char
'b' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
digit ([Int] -> [Int]
forall a. [a] -> [a]
reverse [Int
0 .. Int
changeSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char
' '] [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
changeIDCode
where
(Natural
mask, Natural
val) = Value
changeValue
digit :: Int -> Char
digit Int
d = case (Natural -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Natural
mask Int
d, Natural -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Natural
val Int
d) of
(Bool
False,Bool
False) -> Char
'0'
(Bool
False,Bool
True) -> Char
'1'
(Bool
True,Bool
_) -> Char
'x'
headerDate :: [Text]
headerDate = [Text
"$date", [Char] -> Text
Text.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ UTCTime -> [Char]
iso8601Format UTCTime
now, Text
"$end"]
#ifdef CABAL
clashVer :: [Char]
clashVer = Version -> [Char]
Data.Version.showVersion Version
Paths_clash_prelude.version
#else
clashVer = "development"
#endif
headerVersion :: [Text]
headerVersion = [Text
"$version", Text
"Generated by Clash", [Char] -> Text
Text.pack [Char]
clashVer , Text
"$end"]
headerComment :: [Text]
headerComment = [Text
"$comment", Text
"No comment", Text
"$end"]
dumpVCD#
:: NFDataX a
=> IORef TraceMap
-> (Int, Int)
-> Signal dom a
-> [String]
-> IO (Either String Text.Text)
dumpVCD# :: forall a (dom :: Domain).
NFDataX a =>
IORef TraceMap
-> (Int, Int)
-> Signal dom a
-> [[Char]]
-> IO (Either [Char] Text)
dumpVCD# IORef TraceMap
traceMap (Int, Int)
slice Signal dom a
signal [[Char]]
traceNames = do
IORef TraceMap -> Signal dom a -> [[Char]] -> IO ()
forall a (dom :: Domain).
NFDataX a =>
IORef TraceMap -> Signal dom a -> [[Char]] -> IO ()
waitForTraces# IORef TraceMap
traceMap Signal dom a
signal [[Char]]
traceNames
m <- IORef TraceMap -> IO TraceMap
forall a. IORef a -> IO a
readIORef IORef TraceMap
traceMap
fmap (dumpVCD0# slice m) getCurrentTime
dumpVCD
:: NFDataX a
=> (Int, Int)
-> Signal dom a
-> [String]
-> IO (Either String Text.Text)
dumpVCD :: forall a (dom :: Domain).
NFDataX a =>
(Int, Int) -> Signal dom a -> [[Char]] -> IO (Either [Char] Text)
dumpVCD = IORef TraceMap
-> (Int, Int)
-> Signal dom a
-> [[Char]]
-> IO (Either [Char] Text)
forall a (dom :: Domain).
NFDataX a =>
IORef TraceMap
-> (Int, Int)
-> Signal dom a
-> [[Char]]
-> IO (Either [Char] Text)
dumpVCD# IORef TraceMap
traceMap#
dumpReplayable
:: forall a dom
. NFDataX a
=> Int
-> Signal dom a
-> String
-> IO ByteString
dumpReplayable :: forall a (dom :: Domain).
NFDataX a =>
Int -> Signal dom a -> [Char] -> IO TypeRepBS
dumpReplayable Int
n Signal dom a
oSignal [Char]
traceName = do
IORef TraceMap -> Signal dom a -> [[Char]] -> IO ()
forall a (dom :: Domain).
NFDataX a =>
IORef TraceMap -> Signal dom a -> [[Char]] -> IO ()
waitForTraces# IORef TraceMap
traceMap# Signal dom a
oSignal [[Char]
traceName]
replaySignal <- (TraceMap -> [Char] -> (TypeRepBS, Int, Int, [Value])
forall k a. Ord k => Map k a -> k -> a
Map.! [Char]
traceName) (TraceMap -> (TypeRepBS, Int, Int, [Value]))
-> IO TraceMap -> IO (TypeRepBS, Int, Int, [Value])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef TraceMap -> IO TraceMap
forall a. IORef a -> IO a
readIORef IORef TraceMap
traceMap#
let (tRep, _period, _width, samples) = replaySignal
pure (ByteStringLazy.concat (tRep : map encode (take n samples)))
replay
:: forall a dom n
. ( Typeable a
, NFDataX a
, BitPack a
, KnownNat n
, n ~ BitSize a )
=> ByteString
-> Either String (Signal dom a)
replay :: forall a (dom :: Domain) (n :: Natural).
(Typeable a, NFDataX a, BitPack a, KnownNat n, n ~ BitSize a) =>
TypeRepBS -> Either [Char] (Signal dom a)
replay TypeRepBS
bytes0 = Either [Char] (Signal dom a)
samples1
where
samples1 :: Either [Char] (Signal dom a)
samples1 =
case TypeRepBS
-> Either
(TypeRepBS, ByteOffset, [Char]) (TypeRepBS, ByteOffset, TypeRep a)
forall a.
Binary a =>
TypeRepBS
-> Either
(TypeRepBS, ByteOffset, [Char]) (TypeRepBS, ByteOffset, a)
decodeOrFail TypeRepBS
bytes0 of
Left (TypeRepBS
_, ByteOffset
_, [Char]
err) ->
[Char] -> Either [Char] (Signal dom a)
forall a b. a -> Either a b
Left ([Char]
"Failed to decode typeRep. Parser reported:\n\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
err)
Right (TypeRepBS
bytes1, ByteOffset
_, TypeRep a
_ :: TypeRep a) ->
let samples0 :: [Either [Char] a]
samples0 = TypeRepBS -> [Either [Char] a]
forall a (n :: Natural).
(BitPack a, KnownNat n, n ~ BitSize a) =>
TypeRepBS -> [Either [Char] a]
decodeSamples TypeRepBS
bytes1 in
let err :: [Char]
err = [Char]
"Failed to decode value in signal. Parser reported:\n\n " in
Signal dom a -> Either [Char] (Signal dom a)
forall a b. b -> Either a b
Right ([a] -> Signal dom a
forall a (dom :: Domain). NFDataX a => [a] -> Signal dom a
fromList ((Either [Char] a -> a) -> [Either [Char] a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (([Char] -> a) -> (a -> a) -> Either [Char] a -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([Char] -> a
forall a. HasCallStack => [Char] -> a
error ([Char] -> a) -> ([Char] -> [Char]) -> [Char] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char]
err [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)) a -> a
forall a. a -> a
id) [Either [Char] a]
samples0))
decodeSamples
:: forall a n
. ( BitPack a
, KnownNat n
, n ~ BitSize a )
=> ByteString
-> [Either String a]
decodeSamples :: forall a (n :: Natural).
(BitPack a, KnownNat n, n ~ BitSize a) =>
TypeRepBS -> [Either [Char] a]
decodeSamples TypeRepBS
bytes0 =
case TypeRepBS
-> Either
(TypeRepBS, ByteOffset, [Char]) (TypeRepBS, ByteOffset, Value)
forall a.
Binary a =>
TypeRepBS
-> Either
(TypeRepBS, ByteOffset, [Char]) (TypeRepBS, ByteOffset, a)
decodeOrFail TypeRepBS
bytes0 of
Left (TypeRepBS
_, ByteOffset
_, [Char]
err) ->
[[Char] -> Either [Char] a
forall a b. a -> Either a b
Left [Char]
err]
Right (TypeRepBS
bytes1, ByteOffset
_, (Natural
m, Natural
v)) ->
(a -> Either [Char] a
forall a b. b -> Either a b
Right (BitVector (BitSize a) -> a
forall a. BitPack a => BitVector (BitSize a) -> a
unpack (Natural -> Natural -> BitVector n
forall (n :: Natural). Natural -> Natural -> BitVector n
BV Natural
m Natural
v))) Either [Char] a -> [Either [Char] a] -> [Either [Char] a]
forall a. a -> [a] -> [a]
: TypeRepBS -> [Either [Char] a]
forall a (n :: Natural).
(BitPack a, KnownNat n, n ~ BitSize a) =>
TypeRepBS -> [Either [Char] a]
decodeSamples TypeRepBS
bytes1
waitForTraces#
:: NFDataX a
=> IORef TraceMap
-> Signal dom a
-> [String]
-> IO ()
waitForTraces# :: forall a (dom :: Domain).
NFDataX a =>
IORef TraceMap -> Signal dom a -> [[Char]] -> IO ()
waitForTraces# IORef TraceMap
traceMap Signal dom a
signal [[Char]]
traceNames = do
IORef TraceMap -> TraceMap -> IO ()
forall a. IORef a -> a -> IO ()
atomicWriteIORef IORef TraceMap
traceMap TraceMap
forall k a. Map k a
Map.empty
rest <- (Signal dom a -> [Char] -> IO (Signal dom a))
-> Signal dom a -> [[Char]] -> IO (Signal dom a)
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Signal dom a -> [Char] -> IO (Signal dom a)
go Signal dom a
signal [[Char]]
traceNames
seq rest (return ())
where
go :: Signal dom a -> [Char] -> IO (Signal dom a)
go (a
s0 :- Signal dom a
ss) [Char]
nm = do
m <- IORef TraceMap -> IO TraceMap
forall a. IORef a -> IO a
readIORef IORef TraceMap
traceMap
if Map.member nm m then
deepseqX s0 (return ss)
else
deepseqX
s0
(go ss nm)