{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}
{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Clash.Explicit.Signal
(
Signal
, BiSignalIn
, BiSignalOut
, BiSignalDefault(..)
, Domain
, KnownDomain(..)
, KnownConfiguration
, ActiveEdge(..)
, SActiveEdge(..)
, InitBehavior(..)
, SInitBehavior(..)
, ResetKind(..)
, SResetKind(..)
, ResetPolarity(..)
, SResetPolarity(..)
, DomainConfiguration(..)
, SDomainConfiguration(..)
, DomainPeriod
, DomainActiveEdge
, DomainResetKind
, DomainInitBehavior
, DomainResetPolarity
, System
, XilinxSystem
, IntelSystem
, vSystem
, vIntelSystem
, vXilinxSystem
, VDomainConfiguration(..)
, vDomain
, createDomain
, knownVDomain
, clockPeriod
, activeEdge
, resetKind
, initBehavior
, resetPolarity
, Enable
, toEnable
, fromEnable
, enableGen
, Clock
, freqCalc
, periodToHz
, hzToPeriod
, unsafeSynchronizer
, veryUnsafeSynchronizer
, Reset
, unsafeToReset
, unsafeFromReset
, unsafeToHighPolarity
, unsafeToLowPolarity
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, convertReset
, resetSynchronizer
, holdReset
, enable
, dflipflop
, delay
, delayMaybe
, delayEn
, register
, regMaybe
, regEn
, mux
, clockGen
, resetGen
, resetGenN
, systemClockGen
, systemResetGen
, (.&&.), (.||.)
, Bundle(..)
, EmptyTuple(..)
, TaggedEmptyTuple(..)
, simulate
, simulateB
, simulateWithReset
, simulateWithResetN
, simulate_lazy
, simulateB_lazy
, sample
, sampleN
, sampleWithReset
, sampleWithResetN
, fromList
, fromListWithReset
, sample_lazy
, sampleN_lazy
, fromList_lazy
, testFor
, (.==.), (./=.)
, (.<.), (.<=.), (.>=.), (.>.)
, veryUnsafeToBiSignalIn
, readFromBiSignal
, writeToBiSignal
, mergeBiSignalOuts
)
where
import Data.Maybe (isJust)
import GHC.TypeLits (type (+), type (<=))
import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Class.Num (satSucc, SaturationMode(SatBound))
import Clash.Promoted.Nat (SNat(..), snatToNum)
import Clash.Signal.Bundle
(Bundle (..), EmptyTuple(..), TaggedEmptyTuple(..), vecBundle#)
import Clash.Signal.BiSignal
import Clash.Signal.Internal
import Clash.Signal.Internal.Ambiguous
(knownVDomain, clockPeriod, activeEdge, resetKind, initBehavior, resetPolarity)
import Clash.Sized.Index (Index)
import qualified Clash.Sized.Vector
import Clash.XException (NFDataX, deepErrorX, fromJustX)
systemClockGen
:: Clock System
systemClockGen :: Clock System
systemClockGen = Clock System
forall (dom :: Domain). KnownDomain dom => Clock dom
clockGen
systemResetGen ::Reset System
systemResetGen :: Reset System
systemResetGen = Reset System
forall (dom :: Domain). KnownDomain dom => Reset dom
resetGen
resetSynchronizer
:: forall dom
. KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> Reset dom
resetSynchronizer :: Clock dom -> Reset dom -> Enable dom -> Reset dom
resetSynchronizer clk :: Clock dom
clk rst :: Reset dom
rst en :: Enable dom
en =
case forall (dom :: Domain) (sync :: ResetKind).
(KnownDomain dom, DomainResetKind dom ~ sync) =>
SResetKind sync
forall (sync :: ResetKind).
(KnownDomain dom,
DomainConfigurationResetKind (KnownConf dom) ~ sync) =>
SResetKind sync
resetKind @dom of
SAsynchronous ->
let isActiveHigh :: Bool
isActiveHigh = case forall (dom :: Domain) (polarity :: ResetPolarity).
(KnownDomain dom, DomainResetPolarity dom ~ polarity) =>
SResetPolarity polarity
forall (polarity :: ResetPolarity).
(KnownDomain dom,
DomainConfigurationResetPolarity (KnownConf dom) ~ polarity) =>
SResetPolarity polarity
resetPolarity @dom of { SActiveHigh -> Bool
True; _ -> Bool
False }
r1 :: Signal dom Bool
r1 = Clock dom
-> Reset dom
-> Enable dom
-> Bool
-> Signal dom Bool
-> Signal dom Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en Bool
isActiveHigh (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Bool -> Bool
not Bool
isActiveHigh))
r2 :: Signal dom Bool
r2 = Clock dom
-> Reset dom
-> Enable dom
-> Bool
-> Signal dom Bool
-> Signal dom Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en Bool
isActiveHigh Signal dom Bool
r1
in Signal dom Bool -> Reset dom
forall (dom :: Domain). Signal dom Bool -> Reset dom
unsafeToReset Signal dom Bool
r2
SSynchronous ->
Reset dom
rst
freqCalc :: Double -> Integer
freqCalc :: Double -> Integer
freqCalc = Natural -> Integer
forall a. Integral a => a -> Integer
toInteger (Natural -> Integer) -> (Double -> Natural) -> Double -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Double -> Natural
Double -> Natural
hzToPeriod
{-# DEPRECATED freqCalc "Use 'hzToPeriod' instead." #-}
unsafeSynchronizer
:: forall dom1 dom2 a
. ( KnownDomain dom1
, KnownDomain dom2 )
=> Clock dom1
-> Clock dom2
-> Signal dom1 a
-> Signal dom2 a
unsafeSynchronizer :: Clock dom1 -> Clock dom2 -> Signal dom1 a -> Signal dom2 a
unsafeSynchronizer _clk1 :: Clock dom1
_clk1 _clk2 :: Clock dom2
_clk2 =
Int -> Int -> Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Int -> Int -> Signal dom1 a -> Signal dom2 a
veryUnsafeSynchronizer
(SNat (DomainConfigurationPeriod (KnownConf dom1)) -> Int
forall a (n :: Nat). Num a => SNat n -> a
snatToNum (forall (period :: Nat).
(KnownDomain dom1,
DomainConfigurationPeriod (KnownConf dom1) ~ period) =>
SNat period
forall (dom :: Domain) (period :: Nat).
(KnownDomain dom, DomainPeriod dom ~ period) =>
SNat period
clockPeriod @dom1))
(SNat (DomainConfigurationPeriod (KnownConf dom2)) -> Int
forall a (n :: Nat). Num a => SNat n -> a
snatToNum (forall (period :: Nat).
(KnownDomain dom2,
DomainConfigurationPeriod (KnownConf dom2) ~ period) =>
SNat period
forall (dom :: Domain) (period :: Nat).
(KnownDomain dom, DomainPeriod dom ~ period) =>
SNat period
clockPeriod @dom2))
{-# INLINE unsafeSynchronizer #-}
veryUnsafeSynchronizer
:: Int
-> Int
-> Signal dom1 a
-> Signal dom2 a
veryUnsafeSynchronizer :: Int -> Int -> Signal dom1 a -> Signal dom2 a
veryUnsafeSynchronizer t1 :: Int
t1 t2 :: Int
t2
| Int
t1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
t2 = Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Signal dom1 a -> Signal dom2 a
same
| Bool
otherwise = Int -> Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Int -> Signal dom1 a -> Signal dom2 a
go 0
where
same :: Signal dom1 a -> Signal dom2 a
same :: Signal dom1 a -> Signal dom2 a
same (s :: a
s :- ss :: Signal dom1 a
ss) = a
s a -> Signal dom2 a -> Signal dom2 a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Signal dom1 a -> Signal dom2 a
same Signal dom1 a
ss
go :: Int -> Signal dom1 a -> Signal dom2 a
go :: Int -> Signal dom1 a -> Signal dom2 a
go relativeTime :: Int
relativeTime (a :: a
a :- s :: Signal dom1 a
s)
| Int
relativeTime Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = a
a a -> Signal dom2 a -> Signal dom2 a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Int -> Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Int -> Signal dom1 a -> Signal dom2 a
go (Int
relativeTime Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
t2) (a
a a -> Signal dom1 a -> Signal dom1 a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom1 a
s)
| Bool
otherwise = Int -> Signal dom1 a -> Signal dom2 a
forall (dom1 :: Domain) a (dom2 :: Domain).
Int -> Signal dom1 a -> Signal dom2 a
go (Int
relativeTime Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
t1) Signal dom1 a
s
{-# NOINLINE veryUnsafeSynchronizer #-}
{-# ANN veryUnsafeSynchronizer hasBlackBox #-}
enable
:: Enable dom
-> Signal dom Bool
-> Enable dom
enable :: Enable dom -> Signal dom Bool -> Enable dom
enable e0 :: Enable dom
e0 e1 :: Signal dom Bool
e1 =
Signal dom Bool -> Enable dom
forall (dom :: Domain). Signal dom Bool -> Enable dom
toEnable (Enable dom -> Signal dom Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable Enable dom
e0 Signal dom Bool -> Signal dom Bool -> Signal dom Bool
forall (f :: Type -> Type).
Applicative f =>
f Bool -> f Bool -> f Bool
.&&. Signal dom Bool
e1)
dflipflop
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Signal dom a
-> Signal dom a
dflipflop :: Clock dom -> Signal dom a -> Signal dom a
dflipflop clk :: Clock dom
clk i :: Signal dom a
i =
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay
Clock dom
clk
(Signal dom Bool -> Enable dom
forall (dom :: Domain). Signal dom Bool -> Enable dom
toEnable (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
True))
(String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX "First value of dflipflop undefined")
Signal dom a
i
{-# INLINE dflipflop #-}
delay
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Enable dom
-> a
-> Signal dom a
-> Signal dom a
delay :: Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay = Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay#
{-# INLINE delay #-}
delayMaybe
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Enable dom
-> a
-> Signal dom (Maybe a)
-> Signal dom a
delayMaybe :: Clock dom
-> Enable dom -> a -> Signal dom (Maybe a) -> Signal dom a
delayMaybe clk :: Clock dom
clk gen :: Enable dom
gen dflt :: a
dflt i :: Signal dom (Maybe a)
i =
Clock dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
delayEn Clock dom
clk Enable dom
gen a
dflt (Maybe a -> Bool
forall a. Maybe a -> Bool
isJust (Maybe a -> Bool) -> Signal dom (Maybe a) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe a)
i) (Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe a -> a) -> Signal dom (Maybe a) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe a)
i)
{-# INLINE delayMaybe #-}
delayEn
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
delayEn :: Clock dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
delayEn clk :: Clock dom
clk gen :: Enable dom
gen dflt :: a
dflt en :: Signal dom Bool
en i :: Signal dom a
i =
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay Clock dom
clk (Enable dom -> Signal dom Bool -> Enable dom
forall (dom :: Domain). Enable dom -> Signal dom Bool -> Enable dom
enable Enable dom
gen Signal dom Bool
en) a
dflt Signal dom a
i
{-# INLINE delayEn #-}
register
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Reset dom
-> Enable dom
-> a
-> Signal dom a
-> Signal dom a
register :: Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register clk :: Clock dom
clk rst :: Reset dom
rst gen :: Enable dom
gen initial :: a
initial i :: Signal dom a
i =
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
register# Clock dom
clk Reset dom
rst Enable dom
gen a
initial a
initial Signal dom a
i
{-# INLINE register #-}
regMaybe
:: ( KnownDomain dom
, NFDataX a )
=> Clock dom
-> Reset dom
-> Enable dom
-> a
-> Signal dom (Maybe a)
-> Signal dom a
regMaybe :: Clock dom
-> Reset dom
-> Enable dom
-> a
-> Signal dom (Maybe a)
-> Signal dom a
regMaybe clk :: Clock dom
clk rst :: Reset dom
rst en :: Enable dom
en initial :: a
initial iM :: Signal dom (Maybe a)
iM =
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst (Enable dom -> Signal dom Bool -> Enable dom
forall (dom :: Domain). Enable dom -> Signal dom Bool -> Enable dom
enable Enable dom
en ((Maybe a -> Bool) -> Signal dom (Maybe a) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe a -> Bool
forall a. Maybe a -> Bool
isJust Signal dom (Maybe a)
iM)) a
initial ((Maybe a -> a) -> Signal dom (Maybe a) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJustX Signal dom (Maybe a)
iM)
{-# INLINE regMaybe #-}
regEn
:: ( KnownDomain dom
, NFDataX a
)
=> Clock dom
-> Reset dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
regEn :: Clock dom
-> Reset dom
-> Enable dom
-> a
-> Signal dom Bool
-> Signal dom a
-> Signal dom a
regEn clk :: Clock dom
clk rst :: Reset dom
rst gen :: Enable dom
gen initial :: a
initial en :: Signal dom Bool
en i :: Signal dom a
i =
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst (Enable dom -> Signal dom Bool -> Enable dom
forall (dom :: Domain). Enable dom -> Signal dom Bool -> Enable dom
enable Enable dom
gen Signal dom Bool
en) a
initial Signal dom a
i
{-# INLINE regEn #-}
simulateWithReset
:: forall dom a b m
. ( KnownDomain dom
, NFDataX a
, NFDataX b
, 1 <= m )
=> SNat m
-> a
-> ( KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> Signal dom a
-> Signal dom b )
-> [a]
-> [b]
simulateWithReset :: SNat m
-> a
-> (KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b)
-> [a]
-> [b]
simulateWithReset m :: SNat m
m resetVal :: a
resetVal f :: KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b
f as :: [a]
as =
Int -> [b] -> [b]
forall a. Int -> [a] -> [a]
drop (SNat m -> Int
forall a (n :: Nat). Num a => SNat n -> a
snatToNum SNat m
m) [b]
out
where
inp :: [a]
inp = Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (SNat m -> Int
forall a (n :: Nat). Num a => SNat n -> a
snatToNum SNat m
m) a
resetVal [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
as
rst :: Reset dom
rst = SNat m -> Reset dom
forall (dom :: Domain) (n :: Nat).
(KnownDomain dom, 1 <= n) =>
SNat n -> Reset dom
resetGenN @dom SNat m
m
clk :: Clock dom
clk = Clock dom
forall (dom :: Domain). KnownDomain dom => Clock dom
clockGen
en :: Enable dom
en = Enable dom
forall (dom :: Domain). Enable dom
enableGen
out :: [b]
out = (Signal dom a -> Signal dom b) -> [a] -> [b]
forall a b (dom1 :: Domain) (dom2 :: Domain).
(NFDataX a, NFDataX b) =>
(Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
simulate (Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b
KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b
f Clock dom
clk Reset dom
rst Enable dom
forall (dom :: Domain). Enable dom
en) [a]
inp
{-# NOINLINE simulateWithReset #-}
simulateWithResetN
:: ( KnownDomain dom
, NFDataX a
, NFDataX b
, 1 <= m )
=> SNat m
-> a
-> Int
-> ( KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> Signal dom a
-> Signal dom b )
-> [a]
-> [b]
simulateWithResetN :: SNat m
-> a
-> Int
-> (KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b)
-> [a]
-> [b]
simulateWithResetN nReset :: SNat m
nReset resetVal :: a
resetVal nSamples :: Int
nSamples f :: KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b
f as :: [a]
as =
Int -> [b] -> [b]
forall a. Int -> [a] -> [a]
take Int
nSamples (SNat m
-> a
-> (KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b)
-> [a]
-> [b]
forall (dom :: Domain) a b (m :: Nat).
(KnownDomain dom, NFDataX a, NFDataX b, 1 <= m) =>
SNat m
-> a
-> (KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b)
-> [a]
-> [b]
simulateWithReset SNat m
nReset a
resetVal KnownDomain dom =>
Clock dom
-> Reset dom -> Enable dom -> Signal dom a -> Signal dom b
f [a]
as)
{-# INLINE simulateWithResetN #-}
simulateB
:: (Bundle a, Bundle b, NFDataX a, NFDataX b)
=> (Unbundled dom1 a -> Unbundled dom2 b)
-> [a]
-> [b]
simulateB :: (Unbundled dom1 a -> Unbundled dom2 b) -> [a] -> [b]
simulateB f :: Unbundled dom1 a -> Unbundled dom2 b
f = (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
forall a b (dom1 :: Domain) (dom2 :: Domain).
(NFDataX a, NFDataX b) =>
(Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
simulate (Unbundled dom2 b -> Signal dom2 b
forall a (dom :: Domain).
Bundle a =>
Unbundled dom a -> Signal dom a
bundle (Unbundled dom2 b -> Signal dom2 b)
-> (Signal dom1 a -> Unbundled dom2 b)
-> Signal dom1 a
-> Signal dom2 b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Unbundled dom1 a -> Unbundled dom2 b
f (Unbundled dom1 a -> Unbundled dom2 b)
-> (Signal dom1 a -> Unbundled dom1 a)
-> Signal dom1 a
-> Unbundled dom2 b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal dom1 a -> Unbundled dom1 a
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle)
simulateB_lazy
:: (Bundle a, Bundle b)
=> (Unbundled dom1 a -> Unbundled dom2 b)
-> [a]
-> [b]
simulateB_lazy :: (Unbundled dom1 a -> Unbundled dom2 b) -> [a] -> [b]
simulateB_lazy f :: Unbundled dom1 a -> Unbundled dom2 b
f = (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
forall (dom1 :: Domain) a (dom2 :: Domain) b.
(Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
simulate_lazy (Unbundled dom2 b -> Signal dom2 b
forall a (dom :: Domain).
Bundle a =>
Unbundled dom a -> Signal dom a
bundle (Unbundled dom2 b -> Signal dom2 b)
-> (Signal dom1 a -> Unbundled dom2 b)
-> Signal dom1 a
-> Signal dom2 b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Unbundled dom1 a -> Unbundled dom2 b
f (Unbundled dom1 a -> Unbundled dom2 b)
-> (Signal dom1 a -> Unbundled dom1 a)
-> Signal dom1 a
-> Unbundled dom2 b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal dom1 a -> Unbundled dom1 a
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle)
holdReset
:: forall dom n
. KnownDomain dom
=> Clock dom
-> Enable dom
-> SNat n
-> Reset dom
-> Reset dom
holdReset :: Clock dom -> Enable dom -> SNat n -> Reset dom -> Reset dom
holdReset clk :: Clock dom
clk en :: Enable dom
en SNat rst :: Reset dom
rst =
Signal dom Bool -> Reset dom
forall (dom :: Domain).
KnownDomain dom =>
Signal dom Bool -> Reset dom
unsafeFromHighPolarity ((Index (n + 1) -> Index (n + 1) -> Bool
forall a. Eq a => a -> a -> Bool
/=Index (n + 1)
forall a. Bounded a => a
maxBound) (Index (n + 1) -> Bool)
-> Signal dom (Index (n + 1)) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index (n + 1))
counter)
where
counter :: Signal dom (Index (n+1))
counter :: Signal dom (Index (n + 1))
counter = Clock dom
-> Reset dom
-> Enable dom
-> Index (n + 1)
-> Signal dom (Index (n + 1))
-> Signal dom (Index (n + 1))
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en 0 (SaturationMode -> Index (n + 1) -> Index (n + 1)
forall a. SaturatingNum a => SaturationMode -> a -> a
satSucc SaturationMode
SatBound (Index (n + 1) -> Index (n + 1))
-> Signal dom (Index (n + 1)) -> Signal dom (Index (n + 1))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index (n + 1))
counter)
fromListWithReset
:: forall dom a
. (KnownDomain dom, NFDataX a)
=> Reset dom
-> a
-> [a]
-> Signal dom a
fromListWithReset :: Reset dom -> a -> [a] -> Signal dom a
fromListWithReset rst :: Reset dom
rst resetValue :: a
resetValue vals :: [a]
vals =
Signal dom Bool -> [a] -> Signal dom a
go (Reset dom -> Signal dom Bool
forall (dom :: Domain).
KnownDomain dom =>
Reset dom -> Signal dom Bool
unsafeToHighPolarity Reset dom
rst) [a]
vals
where
go :: Signal dom Bool -> [a] -> Signal dom a
go (r :: Bool
r :- rs :: Signal dom Bool
rs) _ | Bool
r = a
resetValue a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom Bool -> [a] -> Signal dom a
go Signal dom Bool
rs [a]
vals
go (_ :- rs :: Signal dom Bool
rs) [] = String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX "fromListWithReset: input ran out" a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom Bool -> [a] -> Signal dom a
go Signal dom Bool
rs []
go (_ :- rs :: Signal dom Bool
rs) (a :: a
a : as :: [a]
as) = a
a a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom Bool -> [a] -> Signal dom a
go Signal dom Bool
rs [a]
as
convertReset
:: forall domA domB
. ( KnownDomain domA
, KnownDomain domB
)
=> Clock domA
-> Clock domB
-> Reset domA
-> Reset domB
convertReset :: Clock domA -> Clock domB -> Reset domA -> Reset domB
convertReset clkA :: Clock domA
clkA clkB :: Clock domB
clkB (Reset domA -> Signal domA Bool
forall (dom :: Domain).
KnownDomain dom =>
Reset dom -> Signal dom Bool
unsafeToHighPolarity -> Signal domA Bool
rstA0) =
Signal domB Bool -> Reset domB
forall (dom :: Domain).
KnownDomain dom =>
Signal dom Bool -> Reset dom
unsafeFromHighPolarity Signal domB Bool
rstA2
where
rstA1 :: Signal domB Bool
rstA1 = Clock domA -> Clock domB -> Signal domA Bool -> Signal domB Bool
forall (dom1 :: Domain) (dom2 :: Domain) a.
(KnownDomain dom1, KnownDomain dom2) =>
Clock dom1 -> Clock dom2 -> Signal dom1 a -> Signal dom2 a
unsafeSynchronizer Clock domA
clkA Clock domB
clkB Signal domA Bool
rstA0
rstA2 :: Signal domB Bool
rstA2 =
case (forall (dom :: Domain) (sync :: ResetKind).
(KnownDomain dom, DomainResetKind dom ~ sync) =>
SResetKind sync
forall (sync :: ResetKind).
(KnownDomain domA,
DomainConfigurationResetKind (KnownConf domA) ~ sync) =>
SResetKind sync
resetKind @domA, forall (dom :: Domain) (sync :: ResetKind).
(KnownDomain dom, DomainResetKind dom ~ sync) =>
SResetKind sync
forall (sync :: ResetKind).
(KnownDomain domB,
DomainConfigurationResetKind (KnownConf domB) ~ sync) =>
SResetKind sync
resetKind @domB) of
(SSynchronous, SSynchronous) -> Signal domB Bool
rstA1
(SAsynchronous, SAsynchronous) -> Signal domB Bool
rstA1
(SSynchronous, SAsynchronous) -> Signal domB Bool
rstA1
(SAsynchronous, SSynchronous) ->
Clock domB
-> Enable domB -> Bool -> Signal domB Bool -> Signal domB Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay Clock domB
clkB Enable domB
forall (dom :: Domain). Enable dom
enableGen Bool
True (Signal domB Bool -> Signal domB Bool)
-> Signal domB Bool -> Signal domB Bool
forall a b. (a -> b) -> a -> b
$
Clock domB
-> Enable domB -> Bool -> Signal domB Bool -> Signal domB Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
delay Clock domB
clkB Enable domB
forall (dom :: Domain). Enable dom
enableGen Bool
True Signal domB Bool
rstA1
sampleWithReset
:: forall dom a m
. ( KnownDomain dom
, NFDataX a
, 1 <= m )
=> SNat m
-> (KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> Signal dom a)
-> [a]
sampleWithReset :: SNat m
-> (KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a)
-> [a]
sampleWithReset nReset :: SNat m
nReset f0 :: KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a
f0 =
let f1 :: Signal dom a
f1 = Clock dom -> Reset dom -> Enable dom -> Signal dom a
KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a
f0 Clock dom
forall (dom :: Domain). KnownDomain dom => Clock dom
clockGen (SNat m -> Reset dom
forall (dom :: Domain) (n :: Nat).
(KnownDomain dom, 1 <= n) =>
SNat n -> Reset dom
resetGenN @dom SNat m
nReset) Enable dom
forall (dom :: Domain). Enable dom
enableGen in
Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop (SNat m -> Int
forall a (n :: Nat). Num a => SNat n -> a
snatToNum SNat m
nReset) (Signal dom a -> [a]
forall (f :: Type -> Type) a. (Foldable f, NFDataX a) => f a -> [a]
sample Signal dom a
f1)
{-# NOINLINE sampleWithReset #-}
sampleWithResetN
:: forall dom a m
. ( KnownDomain dom
, NFDataX a
, 1 <= m )
=> SNat m
-> Int
-> (KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> Signal dom a)
-> [a]
sampleWithResetN :: SNat m
-> Int
-> (KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a)
-> [a]
sampleWithResetN nReset :: SNat m
nReset nSamples :: Int
nSamples f :: KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a
f =
Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
nSamples (SNat m
-> (KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a)
-> [a]
forall (dom :: Domain) a (m :: Nat).
(KnownDomain dom, NFDataX a, 1 <= m) =>
SNat m
-> (KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a)
-> [a]
sampleWithReset SNat m
nReset KnownDomain dom =>
Clock dom -> Reset dom -> Enable dom -> Signal dom a
f)
{-# RULES "sequenceAVecSignal" Clash.Sized.Vector.traverse# (\x -> x) = vecBundle# #-}