{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}

{- |
Copyright  :  (C) 2025-2026, QBayLogic B.V.
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>

Some functions for creating signals for clocks and reset and enable signals.
-}
module Clash.Shockwaves.Internal.Trace.CRE where

import Clash.Explicit.Prelude (noReset, register)
import Clash.Prelude hiding (register, traceSignal)
import qualified Data.List as L
import Data.Tuple.Extra (uncurry3)
import Data.Typeable

import Clash.Shockwaves.LUT
import Clash.Shockwaves.Trace
import Clash.Shockwaves.Waveform hiding (tConst)

{- | A type for displaying clock cycles.
The styles can be configured through style variables @clk_pre@, @clk_a@ and @clk_b@.

__NB__: This is not a traditional clock wave! The clock signal alternates
/every cycle/, rather than going high and low /within/ a cycle.
-}
data ClockWave
  = ClockWave Bool
  | ClockInit
  deriving ((forall x. ClockWave -> Rep ClockWave x)
-> (forall x. Rep ClockWave x -> ClockWave) -> Generic ClockWave
forall x. Rep ClockWave x -> ClockWave
forall x. ClockWave -> Rep ClockWave x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ClockWave -> Rep ClockWave x
from :: forall x. ClockWave -> Rep ClockWave x
$cto :: forall x. Rep ClockWave x -> ClockWave
to :: forall x. Rep ClockWave x -> ClockWave
Generic, Typeable, KnownNat (BitSize ClockWave)
KnownNat (BitSize ClockWave) =>
(ClockWave -> BitVector (BitSize ClockWave))
-> (BitVector (BitSize ClockWave) -> ClockWave)
-> BitPack ClockWave
BitVector (BitSize ClockWave) -> ClockWave
ClockWave -> BitVector (BitSize ClockWave)
forall a.
KnownNat (BitSize a) =>
(a -> BitVector (BitSize a))
-> (BitVector (BitSize a) -> a) -> BitPack a
$cpack :: ClockWave -> BitVector (BitSize ClockWave)
pack :: ClockWave -> BitVector (BitSize ClockWave)
$cunpack :: BitVector (BitSize ClockWave) -> ClockWave
unpack :: BitVector (BitSize ClockWave) -> ClockWave
BitPack, HasCallStack => String -> ClockWave
ClockWave -> Bool
ClockWave -> ()
ClockWave -> ClockWave
(HasCallStack => String -> ClockWave)
-> (ClockWave -> Bool)
-> (ClockWave -> ClockWave)
-> (ClockWave -> ())
-> NFDataX ClockWave
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
$cdeepErrorX :: HasCallStack => String -> ClockWave
deepErrorX :: HasCallStack => String -> ClockWave
$chasUndefined :: ClockWave -> Bool
hasUndefined :: ClockWave -> Bool
$censureSpine :: ClockWave -> ClockWave
ensureSpine :: ClockWave -> ClockWave
$crnfX :: ClockWave -> ()
rnfX :: ClockWave -> ()
NFDataX)

{- | A type for displaying a reset signal.
The styles can be configured through style variables @reset_off@ and @reset_on@.
-}
newtype ResetWave (dom :: Domain) = ResetWave Bool
  deriving ((forall x. ResetWave dom -> Rep (ResetWave dom) x)
-> (forall x. Rep (ResetWave dom) x -> ResetWave dom)
-> Generic (ResetWave dom)
forall x. Rep (ResetWave dom) x -> ResetWave dom
forall x. ResetWave dom -> Rep (ResetWave dom) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (dom :: Symbol) x. Rep (ResetWave dom) x -> ResetWave dom
forall (dom :: Symbol) x. ResetWave dom -> Rep (ResetWave dom) x
$cfrom :: forall (dom :: Symbol) x. ResetWave dom -> Rep (ResetWave dom) x
from :: forall x. ResetWave dom -> Rep (ResetWave dom) x
$cto :: forall (dom :: Symbol) x. Rep (ResetWave dom) x -> ResetWave dom
to :: forall x. Rep (ResetWave dom) x -> ResetWave dom
Generic, Typeable, KnownNat (BitSize (ResetWave dom))
KnownNat (BitSize (ResetWave dom)) =>
(ResetWave dom -> BitVector (BitSize (ResetWave dom)))
-> (BitVector (BitSize (ResetWave dom)) -> ResetWave dom)
-> BitPack (ResetWave dom)
BitVector (BitSize (ResetWave dom)) -> ResetWave dom
ResetWave dom -> BitVector (BitSize (ResetWave dom))
forall a.
KnownNat (BitSize a) =>
(a -> BitVector (BitSize a))
-> (BitVector (BitSize a) -> a) -> BitPack a
forall (dom :: Symbol). KnownNat (BitSize (ResetWave dom))
forall (dom :: Symbol).
BitVector (BitSize (ResetWave dom)) -> ResetWave dom
forall (dom :: Symbol).
ResetWave dom -> BitVector (BitSize (ResetWave dom))
$cpack :: forall (dom :: Symbol).
ResetWave dom -> BitVector (BitSize (ResetWave dom))
pack :: ResetWave dom -> BitVector (BitSize (ResetWave dom))
$cunpack :: forall (dom :: Symbol).
BitVector (BitSize (ResetWave dom)) -> ResetWave dom
unpack :: BitVector (BitSize (ResetWave dom)) -> ResetWave dom
BitPack, HasCallStack => String -> ResetWave dom
ResetWave dom -> Bool
ResetWave dom -> ()
ResetWave dom -> ResetWave dom
(HasCallStack => String -> ResetWave dom)
-> (ResetWave dom -> Bool)
-> (ResetWave dom -> ResetWave dom)
-> (ResetWave dom -> ())
-> NFDataX (ResetWave dom)
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
forall (dom :: Symbol). HasCallStack => String -> ResetWave dom
forall (dom :: Symbol). ResetWave dom -> Bool
forall (dom :: Symbol). ResetWave dom -> ()
forall (dom :: Symbol). ResetWave dom -> ResetWave dom
$cdeepErrorX :: forall (dom :: Symbol). HasCallStack => String -> ResetWave dom
deepErrorX :: HasCallStack => String -> ResetWave dom
$chasUndefined :: forall (dom :: Symbol). ResetWave dom -> Bool
hasUndefined :: ResetWave dom -> Bool
$censureSpine :: forall (dom :: Symbol). ResetWave dom -> ResetWave dom
ensureSpine :: ResetWave dom -> ResetWave dom
$crnfX :: forall (dom :: Symbol). ResetWave dom -> ()
rnfX :: ResetWave dom -> ()
NFDataX)

{- | A type for displaying an enable signal.
The styles can be configured through style variables @enable_off@ and @enable_on@.
-}
newtype EnableWave = EnableWave Bool
  deriving ((forall x. EnableWave -> Rep EnableWave x)
-> (forall x. Rep EnableWave x -> EnableWave) -> Generic EnableWave
forall x. Rep EnableWave x -> EnableWave
forall x. EnableWave -> Rep EnableWave x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EnableWave -> Rep EnableWave x
from :: forall x. EnableWave -> Rep EnableWave x
$cto :: forall x. Rep EnableWave x -> EnableWave
to :: forall x. Rep EnableWave x -> EnableWave
Generic, Typeable, KnownNat (BitSize EnableWave)
KnownNat (BitSize EnableWave) =>
(EnableWave -> BitVector (BitSize EnableWave))
-> (BitVector (BitSize EnableWave) -> EnableWave)
-> BitPack EnableWave
BitVector (BitSize EnableWave) -> EnableWave
EnableWave -> BitVector (BitSize EnableWave)
forall a.
KnownNat (BitSize a) =>
(a -> BitVector (BitSize a))
-> (BitVector (BitSize a) -> a) -> BitPack a
$cpack :: EnableWave -> BitVector (BitSize EnableWave)
pack :: EnableWave -> BitVector (BitSize EnableWave)
$cunpack :: BitVector (BitSize EnableWave) -> EnableWave
unpack :: BitVector (BitSize EnableWave) -> EnableWave
BitPack, HasCallStack => String -> EnableWave
EnableWave -> Bool
EnableWave -> ()
EnableWave -> EnableWave
(HasCallStack => String -> EnableWave)
-> (EnableWave -> Bool)
-> (EnableWave -> EnableWave)
-> (EnableWave -> ())
-> NFDataX EnableWave
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
$cdeepErrorX :: HasCallStack => String -> EnableWave
deepErrorX :: HasCallStack => String -> EnableWave
$chasUndefined :: EnableWave -> Bool
hasUndefined :: EnableWave -> Bool
$censureSpine :: EnableWave -> EnableWave
ensureSpine :: EnableWave -> EnableWave
$crnfX :: EnableWave -> ()
rnfX :: EnableWave -> ()
NFDataX)

{- | A type for displaying clock, reset and enable signals.
See t'ClockWave', t'ResetWave' and t'EnableWave'.
It contains these signals as subsignals. The toplevel signal displays the clock
during normal operation, reset when it is active, and enable when it is low.
The combined style of both being active can be configured through the style
vairable @reset_on_enable_off@.
-}
data CREWave dom = CREWave {forall (dom :: Symbol). CREWave dom -> ClockWave
clock :: ClockWave, forall (dom :: Symbol). CREWave dom -> ResetWave dom
reset :: ResetWave dom, forall (dom :: Symbol). CREWave dom -> EnableWave
enable :: EnableWave}
  deriving ((forall x. CREWave dom -> Rep (CREWave dom) x)
-> (forall x. Rep (CREWave dom) x -> CREWave dom)
-> Generic (CREWave dom)
forall x. Rep (CREWave dom) x -> CREWave dom
forall x. CREWave dom -> Rep (CREWave dom) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (dom :: Symbol) x. Rep (CREWave dom) x -> CREWave dom
forall (dom :: Symbol) x. CREWave dom -> Rep (CREWave dom) x
$cfrom :: forall (dom :: Symbol) x. CREWave dom -> Rep (CREWave dom) x
from :: forall x. CREWave dom -> Rep (CREWave dom) x
$cto :: forall (dom :: Symbol) x. Rep (CREWave dom) x -> CREWave dom
to :: forall x. Rep (CREWave dom) x -> CREWave dom
Generic, Typeable, KnownNat (BitSize (CREWave dom))
KnownNat (BitSize (CREWave dom)) =>
(CREWave dom -> BitVector (BitSize (CREWave dom)))
-> (BitVector (BitSize (CREWave dom)) -> CREWave dom)
-> BitPack (CREWave dom)
BitVector (BitSize (CREWave dom)) -> CREWave dom
CREWave dom -> BitVector (BitSize (CREWave dom))
forall a.
KnownNat (BitSize a) =>
(a -> BitVector (BitSize a))
-> (BitVector (BitSize a) -> a) -> BitPack a
forall (dom :: Symbol). KnownNat (BitSize (CREWave dom))
forall (dom :: Symbol).
BitVector (BitSize (CREWave dom)) -> CREWave dom
forall (dom :: Symbol).
CREWave dom -> BitVector (BitSize (CREWave dom))
$cpack :: forall (dom :: Symbol).
CREWave dom -> BitVector (BitSize (CREWave dom))
pack :: CREWave dom -> BitVector (BitSize (CREWave dom))
$cunpack :: forall (dom :: Symbol).
BitVector (BitSize (CREWave dom)) -> CREWave dom
unpack :: BitVector (BitSize (CREWave dom)) -> CREWave dom
BitPack, HasCallStack => String -> CREWave dom
CREWave dom -> Bool
CREWave dom -> ()
CREWave dom -> CREWave dom
(HasCallStack => String -> CREWave dom)
-> (CREWave dom -> Bool)
-> (CREWave dom -> CREWave dom)
-> (CREWave dom -> ())
-> NFDataX (CREWave dom)
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
forall (dom :: Symbol). HasCallStack => String -> CREWave dom
forall (dom :: Symbol). CREWave dom -> Bool
forall (dom :: Symbol). CREWave dom -> ()
forall (dom :: Symbol). CREWave dom -> CREWave dom
$cdeepErrorX :: forall (dom :: Symbol). HasCallStack => String -> CREWave dom
deepErrorX :: HasCallStack => String -> CREWave dom
$chasUndefined :: forall (dom :: Symbol). CREWave dom -> Bool
hasUndefined :: CREWave dom -> Bool
$censureSpine :: forall (dom :: Symbol). CREWave dom -> CREWave dom
ensureSpine :: CREWave dom -> CREWave dom
$crnfX :: forall (dom :: Symbol). CREWave dom -> ()
rnfX :: CREWave dom -> ()
NFDataX)
  deriving (Typeable (CREWave dom)
Int
String
[WaveStyle]
BitPack (CREWave dom)
Translator
(Typeable (CREWave dom), BitPack (CREWave dom)) =>
String
-> Translator -> [WaveStyle] -> Int -> Waveform (CREWave dom)
forall a.
(Typeable a, BitPack a) =>
String -> Translator -> [WaveStyle] -> Int -> Waveform a
forall (dom :: Symbol). KnownDomain dom => Typeable (CREWave dom)
forall (dom :: Symbol). KnownDomain dom => Int
forall (dom :: Symbol). KnownDomain dom => String
forall (dom :: Symbol). KnownDomain dom => [WaveStyle]
forall (dom :: Symbol). KnownDomain dom => BitPack (CREWave dom)
forall (dom :: Symbol). KnownDomain dom => Translator
$ctypeName :: forall (dom :: Symbol). KnownDomain dom => String
typeName :: String
$ctranslator :: forall (dom :: Symbol). KnownDomain dom => Translator
translator :: Translator
$cconstructorStyles :: forall (dom :: Symbol). KnownDomain dom => [WaveStyle]
constructorStyles :: [WaveStyle]
$cwidth :: forall (dom :: Symbol). KnownDomain dom => Int
width :: Int
Waveform) via (WaveformForLut (CREWave dom))

vConst :: Render -> Translator
vConst :: Render -> Translator
vConst Render
r = Int -> TranslatorVariant -> Translator
Translator Int
0 (TranslatorVariant -> Translator)
-> TranslatorVariant -> Translator
forall a b. (a -> b) -> a -> b
$ Translation -> TranslatorVariant
TConst (Translation -> TranslatorVariant)
-> Translation -> TranslatorVariant
forall a b. (a -> b) -> a -> b
$ Render -> Translation
tConst Render
r
tConst :: Render -> Translation
tConst :: Render -> Translation
tConst Render
r = Render -> [(String, Translation)] -> Translation
Translation Render
r []

-- the render values used
clkI :: Render
clkI :: Render
clkI = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"NOT RUNNING", String -> WaveStyle -> WaveStyle
WSVar String
"clk_pre" WaveStyle
"#888", Prec
11)
clkA :: Render
clkA :: Render
clkA = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"", String -> WaveStyle -> WaveStyle
WSVar String
"clk_a" WaveStyle
"#fff", Prec
11)
clkB :: Render
clkB :: Render
clkB = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"", String -> WaveStyle -> WaveStyle
WSVar String
"clk_b" WaveStyle
"#83b", Prec
11)

rstOff :: Render
rstOff :: Render
rstOff = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"DEASSERTED", String -> WaveStyle -> WaveStyle
WSVar String
"reset_off" WaveStyle
WSDefault, Prec
11)
rstOn :: Render
rstOn :: Render
rstOn = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"ASSERTED", String -> WaveStyle -> WaveStyle
WSVar String
"reset_on" WaveStyle
WSWarn, Prec
11)
rstOn' :: Render
rstOn' :: Render
rstOn' = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"RESET", String -> WaveStyle -> WaveStyle
WSVar String
"reset_on" WaveStyle
WSWarn, Prec
11)

enOn :: Render
enOn :: Render
enOn = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"ENABLED", String -> WaveStyle -> WaveStyle
WSVar String
"enable_on" WaveStyle
WSDefault, Prec
11)
enOff :: Render
enOff :: Render
enOff = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"DISABLED", String -> WaveStyle -> WaveStyle
WSVar String
"enable_off" WaveStyle
WSWarn, Prec
11)

rstAndDis :: Render
rstAndDis :: Render
rstAndDis = (String, WaveStyle, Prec) -> Render
forall a. a -> Maybe a
Just (String
"DISABLED|RESET", String -> WaveStyle -> WaveStyle
WSVar String
"reset_on_enable_off" WaveStyle
WSWarn, Prec
11)

{- | Control the styles of the clock wave through style variables
@clk_pre@, @clk_a@ and @clk_b@.
-}
instance Waveform ClockWave where
  translator :: Translator
translator =
    Int -> TranslatorVariant -> Translator
Translator Int
2
      (TranslatorVariant -> Translator)
-> TranslatorVariant -> Translator
forall a b. (a -> b) -> a -> b
$ [Translator] -> TranslatorVariant
TSum
        [ Int -> TranslatorVariant -> Translator
Translator Int
1
            (TranslatorVariant -> Translator)
-> TranslatorVariant -> Translator
forall a b. (a -> b) -> a -> b
$ [Translator] -> TranslatorVariant
TSum
              [ Render -> Translator
vConst Render
clkA
              , Render -> Translator
vConst Render
clkB
              ]
        , Render -> Translator
vConst Render
clkI
        ]

{- | Control the styles of the reset wave through style variables
@reset_on@ and @reset_off@.
-}
instance (KnownDomain dom) => Waveform (ResetWave dom) where
  translator :: Translator
translator =
    Int -> TranslatorVariant -> Translator
Translator Int
1
      (TranslatorVariant -> Translator)
-> TranslatorVariant -> Translator
forall a b. (a -> b) -> a -> b
$ [Translator] -> TranslatorVariant
TSum
      ([Translator] -> TranslatorVariant)
-> [Translator] -> TranslatorVariant
forall a b. (a -> b) -> a -> b
$ (Render -> Translator) -> [Render] -> [Translator]
forall a b. (a -> b) -> [a] -> [b]
L.map
        Render -> Translator
vConst
        ( case forall (dom :: Symbol) (polarity :: ResetPolarity).
(KnownDomain dom, DomainResetPolarity dom ~ polarity) =>
SResetPolarity polarity
resetPolarity @dom of
            SResetPolarity (DomainConfigurationResetPolarity (KnownConf dom))
SActiveHigh -> [Render
rstOff, Render
rstOn]
            SResetPolarity (DomainConfigurationResetPolarity (KnownConf dom))
SActiveLow -> [Render
rstOn, Render
rstOff]
        )

{- | Control the styles of the enable wave through style variables
@enable_on@ and @enable_off@.
-}
instance Waveform EnableWave where
  translator :: Translator
translator =
    Int -> TranslatorVariant -> Translator
Translator Int
1
      (TranslatorVariant -> Translator)
-> TranslatorVariant -> Translator
forall a b. (a -> b) -> a -> b
$ [Translator] -> TranslatorVariant
TSum
        [ Render -> Translator
vConst Render
enOff
        , Render -> Translator
vConst Render
enOn
        ]

{- FOURMOLU_DISABLE -}
-- | Control the style of a combined disable and reset through style variable
-- @reset_on_enable_off@.
instance KnownDomain dom => WaveformLUT (CREWave dom) where
  translateL :: CREWave dom -> Translation
translateL = (CREWave dom -> Render)
-> (Render -> CREWave dom -> [(String, Translation)])
-> CREWave dom
-> Translation
forall a.
(a -> Render)
-> (Render -> a -> [(String, Translation)]) -> a -> Translation
translateWith CREWave dom -> Render
displayL Render -> CREWave dom -> [(String, Translation)]
forall a.
(Generic a, WaveformG (Rep a ())) =>
Render -> a -> [(String, Translation)]
splitL
    where 
      displayL :: CREWave dom -> Render
displayL (CREWave ClockWave
c ResetWave dom
r (EnableWave Bool
e)) = case (ClockWave
c,ResetWave dom -> Bool
isRst ResetWave dom
r,Bool
e) of
        (ClockWave
_              ,Bool
True,Bool
False) -> Render
rstAndDis
        (ClockWave
_              ,Bool
True,Bool
_    ) -> Render
rstOn'
        (ClockWave
_              ,Bool
_   ,Bool
False) -> Render
enOff
        (ClockWave
ClockInit      ,Bool
_   ,Bool
_    ) -> Render
clkI
        (ClockWave Bool
False,Bool
_   ,Bool
_    ) -> Render
clkA
        (ClockWave Bool
True ,Bool
_   ,Bool
_    ) -> Render
clkB
        where
          isRst :: ResetWave dom -> Bool
isRst (ResetWave Bool
r') = case forall (dom :: Symbol) (polarity :: ResetPolarity).
(KnownDomain dom, DomainResetPolarity dom ~ polarity) =>
SResetPolarity polarity
resetPolarity @dom of
            SResetPolarity (DomainConfigurationResetPolarity (KnownConf dom))
SActiveHigh -> Bool
r'
            SResetPolarity (DomainConfigurationResetPolarity (KnownConf dom))
SActiveLow  -> Bool -> Bool
not Bool
r'
{- FOURMOLU_ENABLE -}

-- | Produce an alternating signal for a clock.
clkSignal :: (KnownDomain dom) => Clock dom -> Signal dom ClockWave
clkSignal :: forall (dom :: Symbol).
KnownDomain dom =>
Clock dom -> Signal dom ClockWave
clkSignal Clock dom
clk = Signal dom ClockWave
s
 where
  s :: Signal dom ClockWave
s = Clock dom
-> Reset dom
-> Enable dom
-> ClockWave
-> Signal dom ClockWave
-> Signal dom ClockWave
forall (dom :: Symbol) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
forall (dom :: Symbol). KnownDomain dom => Reset dom
noReset Enable dom
forall (dom :: Symbol). Enable dom
enableGen ClockWave
ClockInit Signal dom ClockWave
s'
  s' :: Signal dom ClockWave
s' = ClockWave -> ClockWave
next (ClockWave -> ClockWave)
-> Signal dom ClockWave -> Signal dom ClockWave
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom ClockWave
s
  next :: ClockWave -> ClockWave
next ClockWave
val = case ClockWave
val of
    ClockWave
ClockInit -> Bool -> ClockWave
ClockWave Bool
False
    ClockWave Bool
b -> Bool -> ClockWave
ClockWave (Bool -> Bool
not Bool
b)

{- | Trace a clock signal. Keep in mind that the clock has to be evaluated in order for
the signal to show up. Alternatively, use 'seq' to force evaluation.

The styles can be configured through style variables @clk_pre@, @clk_a@ and @clk_b@.

__NB__: This is not a traditional clock wave! The clock signal alternates
/every cycle/, rather than going high and low /within/ a cycle.
-}
traceClock :: (KnownDomain dom) => String -> Clock dom -> Clock dom
traceClock :: forall (dom :: Symbol).
KnownDomain dom =>
String -> Clock dom -> Clock dom
traceClock String
lbl Clock dom
clk =
  String -> Signal dom ClockWave -> Signal dom ClockWave
forall (dom :: Symbol) a.
(KnownDomain dom, BitPack a, NFDataX a, Typeable a, Waveform a) =>
String -> Signal dom a -> Signal dom a
traceSignal String
lbl (Clock dom -> Signal dom ClockWave
forall (dom :: Symbol).
KnownDomain dom =>
Clock dom -> Signal dom ClockWave
clkSignal Clock dom
clk)
    Signal dom ClockWave -> Clock dom -> Clock dom
forall a b. a -> b -> b
`seq` Clock dom
clk

{- | Trace a reset signal. Keep in mind that the reset has to be evaluated in order for
the signal to show up. Alternatively, use 'seq' to force evaluation.

The styles can be configured through style variables @reset_off@ and @reset_on@.
-}
traceReset :: forall dom. (KnownDomain dom) => String -> Reset dom -> Reset dom
traceReset :: forall (dom :: Symbol).
KnownDomain dom =>
String -> Reset dom -> Reset dom
traceReset String
lbl Reset dom
rst =
  String -> Signal dom (ResetWave dom) -> Signal dom (ResetWave dom)
forall (dom :: Symbol) a.
(KnownDomain dom, BitPack a, NFDataX a, Typeable a, Waveform a) =>
String -> Signal dom a -> Signal dom a
traceSignal String
lbl (forall (dom :: Symbol). Bool -> ResetWave dom
ResetWave @dom (Bool -> ResetWave dom)
-> Signal dom Bool -> Signal dom (ResetWave dom)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Reset dom -> Signal dom Bool
forall (dom :: Symbol). Reset dom -> Signal dom Bool
unsafeFromReset Reset dom
rst)
    Signal dom (ResetWave dom) -> Reset dom -> Reset dom
forall a b. a -> b -> b
`seq` Reset dom
rst

{- | Trace an enable signal. Keep in mind that the enable has to be evaluated in order for
the signal to show up. Alternatively, use 'seq' to force evaluation.

The styles can be configured through style variables @enable_off@ and @enable_on@.
-}
traceEnable :: (KnownDomain dom) => String -> Enable dom -> Enable dom
traceEnable :: forall (dom :: Symbol).
KnownDomain dom =>
String -> Enable dom -> Enable dom
traceEnable String
lbl Enable dom
en =
  String -> Signal dom EnableWave -> Signal dom EnableWave
forall (dom :: Symbol) a.
(KnownDomain dom, BitPack a, NFDataX a, Typeable a, Waveform a) =>
String -> Signal dom a -> Signal dom a
traceSignal String
lbl (Bool -> EnableWave
EnableWave (Bool -> EnableWave) -> Signal dom Bool -> Signal dom EnableWave
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Enable dom -> Signal dom Bool
forall (dom :: Symbol). Enable dom -> Signal dom Bool
fromEnable Enable dom
en)
    Signal dom EnableWave -> Enable dom -> Enable dom
forall a b. a -> b -> b
`seq` Enable dom
en

{- | Create a signal displaying the clock, reset and enable signals.

Example:

> traceClockResetEnable "cre" myDesign clockGen resetGen enableGen

The style of a combined disable and reset can be configured through style variable
@reset_on_enable_off@. For other options, see 'traceClock', 'traceReset' and
'traceEnable'.

__NB__: This does not contain a traditional clock wave! The clock signal alternates
/every cycle/, rather than going high and low /within/ a cycle.
-}
traceClockResetEnable ::
  forall dom a.
  (KnownDomain dom) =>
  String ->
  (Clock dom -> Reset dom -> Enable dom -> a) ->
  (Clock dom -> Reset dom -> Enable dom -> a)
traceClockResetEnable :: forall (dom :: Symbol) a.
KnownDomain dom =>
String
-> (Clock dom -> Reset dom -> Enable dom -> a)
-> Clock dom
-> Reset dom
-> Enable dom
-> a
traceClockResetEnable String
lbl Clock dom -> Reset dom -> Enable dom -> a
f Clock dom
c Reset dom
r Enable dom
e =
  String -> Signal dom (CREWave dom) -> Signal dom (CREWave dom)
forall (dom :: Symbol) a.
(KnownDomain dom, BitPack a, NFDataX a, Typeable a, Waveform a) =>
String -> Signal dom a -> Signal dom a
traceSignal
    String
lbl
    ( (ClockWave -> ResetWave dom -> EnableWave -> CREWave dom)
-> (ClockWave, ResetWave dom, EnableWave) -> CREWave dom
forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 ClockWave -> ResetWave dom -> EnableWave -> CREWave dom
forall (dom :: Symbol).
ClockWave -> ResetWave dom -> EnableWave -> CREWave dom
CREWave
        ((ClockWave, ResetWave dom, EnableWave) -> CREWave dom)
-> Signal dom (ClockWave, ResetWave dom, EnableWave)
-> Signal dom (CREWave dom)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Unbundled dom (ClockWave, ResetWave dom, EnableWave)
-> Signal dom (ClockWave, ResetWave dom, EnableWave)
forall a (dom :: Symbol).
Bundle a =>
Unbundled dom a -> Signal dom a
forall (dom :: Symbol).
Unbundled dom (ClockWave, ResetWave dom, EnableWave)
-> Signal dom (ClockWave, ResetWave dom, EnableWave)
bundle
          ( Clock dom -> Signal dom ClockWave
forall (dom :: Symbol).
KnownDomain dom =>
Clock dom -> Signal dom ClockWave
clkSignal Clock dom
c
          , Bool -> ResetWave dom
forall (dom :: Symbol). Bool -> ResetWave dom
ResetWave (Bool -> ResetWave dom)
-> Signal dom Bool -> Signal dom (ResetWave dom)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Reset dom -> Signal dom Bool
forall (dom :: Symbol). Reset dom -> Signal dom Bool
unsafeFromReset Reset dom
r
          , Bool -> EnableWave
EnableWave (Bool -> EnableWave) -> Signal dom Bool -> Signal dom EnableWave
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Enable dom -> Signal dom Bool
forall (dom :: Symbol). Enable dom -> Signal dom Bool
fromEnable Enable dom
e
          ) ::
        Signal dom (CREWave dom)
    )
    Signal dom (CREWave dom) -> a -> a
forall a b. a -> b -> b
`seq` Clock dom -> Reset dom -> Enable dom -> a
f Clock dom
c Reset dom
r Enable dom
e

-- | Trace a hidden clock signal. See 'traceClock'.
traceHiddenClock :: (KnownDomain dom, HiddenClock dom) => String -> r -> r
traceHiddenClock :: forall (dom :: Symbol) r.
(KnownDomain dom, HiddenClock dom) =>
String -> r -> r
traceHiddenClock String
lbl r
x = String -> Clock dom -> Clock dom
forall (dom :: Symbol).
KnownDomain dom =>
String -> Clock dom -> Clock dom
traceClock String
lbl Clock dom
forall (dom :: Symbol). HiddenClock dom => Clock dom
hasClock Clock dom -> r -> r
forall a b. a -> b -> b
`seq` r
x

-- | Trace a hidden reset signal. See 'traceReset'.
traceHiddenReset :: (KnownDomain dom, HiddenReset dom) => String -> r -> r
traceHiddenReset :: forall (dom :: Symbol) r.
(KnownDomain dom, HiddenReset dom) =>
String -> r -> r
traceHiddenReset String
lbl r
x = String -> Reset dom -> Reset dom
forall (dom :: Symbol).
KnownDomain dom =>
String -> Reset dom -> Reset dom
traceReset String
lbl Reset dom
forall (dom :: Symbol). HiddenReset dom => Reset dom
hasReset Reset dom -> r -> r
forall a b. a -> b -> b
`seq` r
x

-- | Trace a hidden enable signal. See 'traceEnable'.
traceHiddenEnable :: (KnownDomain dom, HiddenEnable dom) => String -> r -> r
traceHiddenEnable :: forall (dom :: Symbol) r.
(KnownDomain dom, HiddenEnable dom) =>
String -> r -> r
traceHiddenEnable String
lbl r
x = String -> Enable dom -> Enable dom
forall (dom :: Symbol).
KnownDomain dom =>
String -> Enable dom -> Enable dom
traceEnable String
lbl Enable dom
forall (dom :: Symbol). HiddenEnable dom => Enable dom
hasEnable Enable dom -> r -> r
forall a b. a -> b -> b
`seq` r
x

-- | Trace hidden clock, reset and enable signals. See 'traceClockResetEnable'.
traceHiddenClockResetEnable ::
  (KnownDomain dom, HiddenClockResetEnable dom) => String -> r -> r
traceHiddenClockResetEnable :: forall (dom :: Symbol) r.
(KnownDomain dom, HiddenClockResetEnable dom) =>
String -> r -> r
traceHiddenClockResetEnable String
lbl = (Clock dom -> Reset dom -> Enable dom -> r) -> r
(KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r) -> r
forall (dom :: Symbol) r.
HiddenClockResetEnable dom =>
(KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r) -> r
hideClockResetEnable ((Clock dom -> Reset dom -> Enable dom -> r) -> r)
-> (r -> Clock dom -> Reset dom -> Enable dom -> r) -> r -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> (Clock dom -> Reset dom -> Enable dom -> r)
-> Clock dom
-> Reset dom
-> Enable dom
-> r
forall (dom :: Symbol) a.
KnownDomain dom =>
String
-> (Clock dom -> Reset dom -> Enable dom -> a)
-> Clock dom
-> Reset dom
-> Enable dom
-> a
traceClockResetEnable String
lbl ((Clock dom -> Reset dom -> Enable dom -> r)
 -> Clock dom -> Reset dom -> Enable dom -> r)
-> (r -> Clock dom -> Reset dom -> Enable dom -> r)
-> r
-> Clock dom
-> Reset dom
-> Enable dom
-> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r -> Clock dom -> Reset dom -> Enable dom -> r
(HiddenClockResetEnable dom => r)
-> KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r
forall (dom :: Symbol) r.
(HiddenClockResetEnable dom => r)
-> KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r
exposeClockResetEnable