Copyright | (C) 2013-2016 University of Twente 2016 Myrtle Software 2017 Google Inc. |
---|---|
License | BSD2 (see the file LICENSE) |
Maintainer | Christiaan Baaij <christiaan.baaij@gmail.com> |
Safe Haskell | Trustworthy |
Language | Haskell2010 |
Extensions |
|
CλaSH has synchronous Signal
s in the form of:
Signal
(domain ::Domain
) a
Where a is the type of the value of the Signal
, for example Int or Bool,
and domain is the clock- (and reset-) domain to which the memory elements
manipulating these Signal
s belong.
The type-parameter, domain, is of the kind Domain
which has types of the
following shape:
data Domain = Dom { domainName ::Symbol
, clkPeriod ::Nat
}
Where domainName is a type-level string (Symbol
) representing
the name of the clock- (and reset-) domain, and clkPeriod is a type-level
natural number (Nat
) representing the clock period (in ps)
of the clock lines in the clock-domain.
- NB: "Bad things"™ happen when you actually use a clock period of
0
, so do not do that! - NB: You should be judicious using a clock with period of
1
as you can never create a clock that goes any faster!
Synopsis
- data Signal (domain :: Domain) a
- data Domain = Dom {
- domainName :: Symbol
- clkPeriod :: Nat
- type System = Dom "system" 10000
- data Clock (domain :: Domain) (gated :: ClockKind)
- data ClockKind
- data Reset (domain :: Domain) (synchronous :: ResetKind)
- data ResetKind
- unsafeFromAsyncReset :: Reset domain Asynchronous -> Signal domain Bool
- unsafeToAsyncReset :: Signal domain Bool -> Reset domain Asynchronous
- fromSyncReset :: Reset domain Synchronous -> Signal domain Bool
- unsafeToSyncReset :: Signal domain Bool -> Reset domain Synchronous
- resetSynchronizer :: Clock domain gated -> Reset domain Asynchronous -> Reset domain Asynchronous
- type HiddenClock domain gated = Hidden "clk" (Clock domain gated)
- hideClock :: HiddenClock domain gated => (Clock domain gated -> r) -> r
- exposeClock :: (HiddenClock domain gated => r) -> Clock domain gated -> r
- withClock :: Clock domain gated -> (HiddenClock domain gated => r) -> r
- hasClock :: HiddenClock domain gated => Clock domain gated
- type HiddenReset domain synchronous = Hidden "rst" (Reset domain synchronous)
- hideReset :: HiddenReset domain synchronous => (Reset domain synchronous -> r) -> r
- exposeReset :: (HiddenReset domain synchronous => r) -> Reset domain synchronous -> r
- withReset :: Reset domain synchronous -> (HiddenReset domain synchronous => r) -> r
- hasReset :: HiddenReset domain synchronous => Reset domain synchronous
- type HiddenClockReset domain gated synchronous = (HiddenClock domain gated, HiddenReset domain synchronous)
- hideClockReset :: HiddenClockReset domain gated synchronous => (Clock domain gated -> Reset domain synchronous -> r) -> r
- exposeClockReset :: (HiddenClockReset domain gated synchronous => r) -> Clock domain gated -> Reset domain synchronous -> r
- withClockReset :: Clock domain gated -> Reset domain synchronous -> (HiddenClockReset domain gated synchronous => r) -> r
- type SystemClockReset = HiddenClockReset System Source Asynchronous
- delay :: (HiddenClock domain gated, HasCallStack) => Signal domain a -> Signal domain a
- register :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain a -> Signal domain a
- regMaybe :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain (Maybe a) -> Signal domain a
- regEn :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain Bool -> Signal domain a -> Signal domain a
- mux :: Applicative f => f Bool -> f a -> f a -> f a
- clockGen :: (domain ~ Dom nm period, KnownSymbol nm, KnownNat period) => Clock domain Source
- tbClockGen :: (domain ~ Dom nm period, KnownSymbol nm, KnownNat period) => Signal domain Bool -> Clock domain Source
- asyncResetGen :: Reset domain Asynchronous
- syncResetGen :: (domain ~ Dom n clkPeriod, KnownNat clkPeriod) => Reset domain Synchronous
- systemClockGen :: Clock System Source
- tbSystemClockGen :: Signal System Bool -> Clock System Source
- systemResetGen :: Reset System Asynchronous
- (.&&.) :: Applicative f => f Bool -> f Bool -> f Bool
- (.||.) :: Applicative f => f Bool -> f Bool -> f Bool
- class Bundle a where
- simulate :: forall gated synchronous domain a b. (NFData a, NFData b) => (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b) -> [a] -> [b]
- simulateB :: forall gated synchronous domain a b. (Bundle a, Bundle b, NFData a, NFData b) => (HiddenClockReset domain gated synchronous => Unbundled domain a -> Unbundled domain b) -> [a] -> [b]
- simulate_lazy :: forall gated synchronous domain a b. (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b) -> [a] -> [b]
- simulateB_lazy :: forall gated synchronous domain a b. (Bundle a, Bundle b) => (HiddenClockReset domain gated synchronous => Unbundled domain a -> Unbundled domain b) -> [a] -> [b]
- sample :: forall gated synchronous domain a. NFData a => (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
- sampleN :: forall gated synchronous domain a. NFData a => Int -> (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
- fromList :: NFData a => [a] -> Signal domain a
- sample_lazy :: forall gated synchronous domain a. (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
- sampleN_lazy :: forall gated synchronous domain a. Int -> (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
- fromList_lazy :: [a] -> Signal domain a
- testFor :: Int -> (HiddenClockReset domain gated synchronous => Signal domain Bool) -> Property
- (.==.) :: (Eq a, Applicative f) => f a -> f a -> f Bool
- (./=.) :: (Eq a, Applicative f) => f a -> f a -> f Bool
- (.<.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
- (.<=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
- (.>=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
- (.>.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
Synchronous signals
data Signal (domain :: Domain) a Source #
CλaSH has synchronous Signal
s in the form of:
Signal
(domain ::Domain
) a
Where a is the type of the value of the Signal
, for example Int or Bool,
and domain is the clock- (and reset-) domain to which the memory elements
manipulating these Signal
s belong.
The type-parameter, domain, is of the kind Domain
which has types of the
following shape:
data Domain = Dom { domainName ::Symbol
, clkPeriod ::Nat
}
Where domainName is a type-level string (Symbol
) representing
the name of the clock- (and reset-) domain, and clkPeriod is a type-level
natural number (Nat
) representing the clock period (in ps)
of the clock lines in the clock-domain.
- NB: "Bad things"™ happen when you actually use a clock period of
0
, so do not do that! - NB: You should be judicious using a clock with period of
1
as you can never create a clock that goes any faster!
Instances
Functor (Signal domain) Source # | |
Applicative (Signal domain) Source # | |
pure :: a -> Signal domain a # (<*>) :: Signal domain (a -> b) -> Signal domain a -> Signal domain b # liftA2 :: (a -> b -> c) -> Signal domain a -> Signal domain b -> Signal domain c # (*>) :: Signal domain a -> Signal domain b -> Signal domain b # (<*) :: Signal domain a -> Signal domain b -> Signal domain a # | |
Foldable (Signal domain) Source # | NB: Not synthesisable NB: In "
|
fold :: Monoid m => Signal domain m -> m # foldMap :: Monoid m => (a -> m) -> Signal domain a -> m # foldr :: (a -> b -> b) -> b -> Signal domain a -> b # foldr' :: (a -> b -> b) -> b -> Signal domain a -> b # foldl :: (b -> a -> b) -> b -> Signal domain a -> b # foldl' :: (b -> a -> b) -> b -> Signal domain a -> b # foldr1 :: (a -> a -> a) -> Signal domain a -> a # foldl1 :: (a -> a -> a) -> Signal domain a -> a # toList :: Signal domain a -> [a] # null :: Signal domain a -> Bool # length :: Signal domain a -> Int # elem :: Eq a => a -> Signal domain a -> Bool # maximum :: Ord a => Signal domain a -> a # minimum :: Ord a => Signal domain a -> a # | |
Traversable (Signal domain) Source # | |
Fractional a => Fractional (Signal domain a) Source # | |
Num a => Num (Signal domain a) Source # | |
(+) :: Signal domain a -> Signal domain a -> Signal domain a # (-) :: Signal domain a -> Signal domain a -> Signal domain a # (*) :: Signal domain a -> Signal domain a -> Signal domain a # negate :: Signal domain a -> Signal domain a # abs :: Signal domain a -> Signal domain a # signum :: Signal domain a -> Signal domain a # fromInteger :: Integer -> Signal domain a # | |
Show a => Show (Signal domain a) Source # | |
Lift a => Lift (Signal domain a) Source # | |
Default a => Default (Signal domain a) Source # | |
Arbitrary a => Arbitrary (Signal domain a) Source # | |
CoArbitrary a => CoArbitrary (Signal domain a) Source # | |
coarbitrary :: Signal domain a -> Gen b -> Gen b |
A domain with a name (Symbol
) and a clock period (Nat
) in ps
Dom | |
|
Clock
Distinction between gated and ungated clocks
Reset
The "kind" of reset
Given a situation where a reset is asserted, and then de-asserted at the active flank of the clock, we can observe the difference between a synchronous reset and an asynchronous reset:
Synchronous reset
registerS :: Clock domain gated -> Reset domain Synchronous -> Signal domain Int -> Signal domain Int registerS = register
>>>
printX (sampleN 4 (registerS (clockGen @System) (syncResetGen @System) 0 (fromList [1,2,3])))
[X,0,2,3]
Asynchronous reset
registerA :: Clock domain gated -> Reset domain Asynchronous -> Signal domain Int -> Signal domain Int registerA = register
>>>
sampleN 4 (registerA (clockGen @System) (asyncResetGen @System) 0 (fromList [1,2,3]))
[0,1,2,3]
Synchronous | Components with a synchronous reset port produce the reset value when:
|
Asynchronous | Components with an asynchronous reset port produce the reset value when:
|
unsafeFromAsyncReset :: Reset domain Asynchronous -> Signal domain Bool Source #
unsafeFromAsyncReset
is unsafe because it can introduce:
unsafeToAsyncReset :: Signal domain Bool -> Reset domain Asynchronous Source #
unsafeToAsyncReset
is unsafe because it can introduce:
- combinational loops
Example
resetSynchronizer
:: Clock domain gated
-> Reset domain 'Asynchronous
-> Reset domain 'Asynchronous
resetSynchronizer clk rst =
let r1 = register clk rst True (pure False)
r2 = register clk rst True r1
in unsafeToAsyncReset
r2
fromSyncReset :: Reset domain Synchronous -> Signal domain Bool Source #
It is safe to treat synchronous resets as Bool
signals
unsafeToSyncReset :: Signal domain Bool -> Reset domain Synchronous Source #
unsafeToSyncReset
is unsafe because:
- It can lead to meta-stability issues in the presence of asynchronous resets.
resetSynchronizer :: Clock domain gated -> Reset domain Asynchronous -> Reset domain Asynchronous Source #
Normally, asynchronous resets can be both asynchronously asserted and
de-asserted. Asynchronous de-assertion can induce meta-stability in the
component which is being reset. To ensure this doesn't happen,
resetSynchronizer
ensures that de-assertion of a reset happens
synchronously. Assertion of the reset remains asynchronous.
Note that asynchronous assertion does not induce meta-stability in the component whose reset is asserted. However, when a component "A" in another clock or reset domain depends on the value of a component "B" being reset, then asynchronous assertion of the reset of component "B" can induce meta-stability in component "A". To prevent this from happening you need to use a proper synchronizer, for example one of the synchronizers in Clash.Explicit.Synchronizer
NB: Assumes the component(s) being reset have an active-high reset port, which all components in clash-prelude have.
Example
topEntity
:: Clock System Source
-> Reset System Asynchronous
-> Signal System Bit
-> Signal System (BitVector 8)
topEntity clk rst key1 =
let (pllOut,pllStable) = altpll (SSymbol @ "altpll50") clk rst
rstSync = resetSynchronizer
pllOut (unsafeToAsyncReset pllStable)
in exposeClockReset leds pllOut rstSync
where
key1R = isRising 1 key1
leds = mealy blinkerT (1,False,0) key1R
Hidden clocks and resets
Clocks and resets are by default implicitly routed to their components. You can see from the type of a component whether it has hidden clock or reset arguments:
It has a hidden clock when it has a:
f :: HiddenClock
domain gated => ...
Constraint.
Or it has a hidden reset when it has a:
g :: HiddenReset
domain synchronous => ...
Constraint.
Or it has both a hidden clock argument and a hidden reset argument when it has a:
h :: HiddenClockReset
domain gated synchronous => ..
Constraint.
Given a component with an explicit clock and reset arguments, you can turn them
into hidden arguments using hideClock
and hideReset
. So given a:
f :: Clock domain gated -> Reset domain synchronous -> Signal domain a -> ...
You hide the clock and reset arguments by:
-- g ::HiddenClockReset
domain gated synchronous => Signal domain a -> ... g =hideClockReset
f
Or, alternatively, by:
-- h :: HiddenClockReset domain gated synchronous => Signal domain a -> ... h = fhasClock
hasReset
Assigning explicit clock and reset arguments to hidden clocks and resets
Given a component:
f :: HiddenClockReset domain gated synchronous => Signal domain Int -> Signal domain Int
which has hidden clock and routed reset arguments, we expose those hidden arguments so that we can explicitly apply them:
-- g :: Clock domain gated -> Reset domain synchronous -> Signal domain Int -> Signal domain Int
g = exposeClockReset
f
or, alternatively, by:
-- h :: Clock domain gated -> Reset domain synchronous -> Signal domain Int -> Signal domain Int h clk rst = withClock clk rst f
Similarly, there are exposeClock
and exposeReset
to connect just expose
the hidden clock or the hidden reset argument.
You will need to explicitly apply clocks and resets when you want to use
components such as PPLs and resetSynchronizer
:
topEntity :: Clock System Source -> Reset System Asynchronous -> Signal System Int -> Signal System Int topEntity clk rst = let (pllOut,pllStable) =altpll
(SSymbol @"altpll50") clk rst rstSync =resetSynchronizer
pllOut (unsafeToAsyncReset
pllStable) inexposeClockReset
f pllOut rstSync
or, using the alternative method:
topEntity2 :: Clock System Source -> Reset System Asynchronous -> Signal System Int -> Signal System Int topEntity2 clk rst = let (pllOut,pllStable) =altpll
(SSymbol @"altpll50") clk rst rstSync =resetSynchronizer
pllOut (unsafeToAsyncReset
pllStable) inwithClockReset
pllOut rstSync f
Hidden clock
type HiddenClock domain gated = Hidden "clk" (Clock domain gated) Source #
A constraint that indicates the component has a hidden Clock
:: HiddenClock domain gated | |
=> (Clock domain gated -> r) | Function whose clock argument you want to hide |
-> r |
Hide the Clock
argument of a component, so it can be routed implicitly.
:: (HiddenClock domain gated => r) | The component with a hidden clock |
-> Clock domain gated -> r | The component with its clock argument exposed |
Expose the hidden Clock
argument of a component, so it can be applied
explicitly
:: Clock domain gated | The |
-> (HiddenClock domain gated => r) | The function with a hidden |
-> r |
hasClock :: HiddenClock domain gated => Clock domain gated Source #
Hidden reset
type HiddenReset domain synchronous = Hidden "rst" (Reset domain synchronous) Source #
A constraint that indicates the component needs a Reset
:: HiddenReset domain synchronous | |
=> (Reset domain synchronous -> r) | Component whose reset argument you want to hide |
-> r |
Hide the Reset
argument of a component, so it can be routed implicitly.
:: (HiddenReset domain synchronous => r) | The component with a hidden reset |
-> Reset domain synchronous -> r | The component with its reset argument exposed |
Expose the hidden Reset
argument of a component, so it can be applied
explicitly
:: Reset domain synchronous | The |
-> (HiddenReset domain synchronous => r) | The function with a hidden |
-> r |
hasReset :: HiddenReset domain synchronous => Reset domain synchronous Source #
Hidden clock and reset
type HiddenClockReset domain gated synchronous = (HiddenClock domain gated, HiddenReset domain synchronous) Source #
:: HiddenClockReset domain gated synchronous | |
=> (Clock domain gated -> Reset domain synchronous -> r) | Component whose clock and reset argument you want to hide |
-> r |
:: (HiddenClockReset domain gated synchronous => r) | The component with hidden clock and reset arguments |
-> Clock domain gated -> Reset domain synchronous -> r | The component with its clock and reset arguments exposed |
Expose the hidden Clock
and Reset
arguments of a component, so they can
be applied explicitly
Click here to read more about hidden clocks and resets
Example
topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8) topEntity = concat testBench :: Signal System Bool testBench = done where testInput = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil) expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil) done = exposeClockReset (expectedOutput (topEntity $ testInput)) clk rst clk = tbSystemClockGen (not <$> done) rst = systemResetGen
:: Clock domain gated | The |
-> Reset domain synchronous | The |
-> (HiddenClockReset domain gated synchronous => r) | |
-> r |
type SystemClockReset = HiddenClockReset System Source Asynchronous Source #
Basic circuit functions
:: (HiddenClock domain gated, HasCallStack) | |
=> Signal domain a | Signal to delay |
-> Signal domain a |
:: (HiddenClockReset domain gated synchronous, HasCallStack) | |
=> a | Reset value
|
-> Signal domain a | |
-> Signal domain a |
:: (HiddenClockReset domain gated synchronous, HasCallStack) | |
=> a | Reset value
|
-> Signal domain (Maybe a) | |
-> Signal domain a |
Version of register
that only updates its content when its second
argument is a Just
value. So given:
sometimes1 = s where s =register
Nothing (switch<$>
s) switch Nothing = Just 1 switch _ = Nothing countSometimes = s where s =regMaybe
0 (plusM (pure
<$>
s) sometimes1) plusM =liftA2
(liftA2 (+))
We get:
>>>
sampleN 8 sometimes1
[Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]>>>
sampleN 8 countSometimes
[0,0,1,1,2,2,3,3]
:: (HiddenClockReset domain gated synchronous, HasCallStack) | |
=> a | Reset value
|
-> Signal domain Bool | |
-> Signal domain a | |
-> Signal domain a |
mux :: Applicative f => f Bool -> f a -> f a -> f a Source #
Simulation and testbench functions
clockGen :: (domain ~ Dom nm period, KnownSymbol nm, KnownNat period) => Clock domain Source Source #
Clock generator for simulations. Do not use this clock generator for
for the testBench function, use tbClockGen
instead.
To be used like:
type DomA = Dom "A" 1000 clkA = clockGen @DomA
tbClockGen :: (domain ~ Dom nm period, KnownSymbol nm, KnownNat period) => Signal domain Bool -> Clock domain Source Source #
Clock generator to be used in the testBench function.
To be used like:
type DomA = Dom "A" 1000 clkA en = clockGen @DomA en
Example
type DomA1 = Dom "A" 1 -- fast, twice as fast as slow type DomB2 = Dom "B" 2 -- slow topEntity :: Clock DomA1 Source -> Reset DomA1 Asynchronous -> Clock DomB2 Source -> Signal DomA1 (Unsigned 8) -> Signal DomB2 (Unsigned 8, Unsigned 8) topEntity clk1 rst1 clk2 i = let h = register clk1 rst1 0 (register clk1 rst1 0 i) l = register clk1 rst1 0 i in unsafeSynchronizer clk1 clk2 (bundle (h,l)) testBench :: Signal DomB2 Bool testBench = done where testInput = stimuliGenerator clkA1 rstA1 $(listToVecTH [1::Unsigned 8,2,3,4,5,6,7,8]) expectedOutput = outputVerifier clkB2 rstB2 $(listToVecTH [(0,0) :: (Unsigned 8, Unsigned 8),(1,2),(3,4),(5,6),(7,8)]) done = expectedOutput (topEntity clkA1 rstA1 clkB2 testInput) done' = not <$> done clkA1 =tbClockGen
@DomA1 (unsafeSynchronizer clkB2 clkA1 done') clkB2 =tbClockGen
@DomB2 done' rstA1 = asyncResetGen @DomA1 rstB2 = asyncResetGen @DomB2
asyncResetGen :: Reset domain Asynchronous Source #
Asynchronous reset generator, for simulations and the testBench function.
To be used like:
type DomA = Dom "A" 1000 rstA = asyncResetGen @DomA
NB: Can only be used for components with an active-high reset port, which all clash-prelude components are.
Example
type Dom2 = Dom "dom" 2 type Dom7 = Dom "dom" 7 type Dom9 = Dom "dom" 9 topEntity :: Clock Dom2 Source -> Clock Dom7 Source -> Clock Dom9 Source -> Signal Dom7 Integer -> Signal Dom9 Integer topEntity clk2 clk7 clk9 i = delay clk9 (unsafeSynchronizer clk2 clk9 (delay clk2 (unsafeSynchronizer clk7 clk2 (delay clk7 i)))) {--} testBench :: Signal Dom9 Bool testBench = done where testInput = stimuliGenerator clk7 rst7 $(listToVecTH [(1::Integer)..10]) expectedOutput = outputVerifier clk9 rst9 ((undefined :> undefined :> Nil) ++ $(listToVecTH ([2,3,4,5,7,8,9,10]::[Integer]))) done = expectedOutput (topEntity clk2 clk7 clk9 testInput) done' = not <$> done clk2 = tbClockGen @Dom2 (unsafeSynchronizer clk9 clk2 done') clk7 = tbClockGen @Dom7 (unsafeSynchronizer clk9 clk7 done') clk9 = tbClockGen @Dom9 done' rst7 =asyncResetGen
@Dom7 rst9 =asyncResetGen
@Dom9
syncResetGen :: (domain ~ Dom n clkPeriod, KnownNat clkPeriod) => Reset domain Synchronous Source #
Synchronous reset generator, for simulations and the testBench function.
To be used like:
type DomA = Dom "A" 1000 rstA = syncResetGen @DomA
NB: Can only be used for components with an active-high reset port, which all clash-prelude components are.
systemClockGen :: Clock System Source Source #
Clock generator for the System
clock domain.
NB: should only be used for simulation, and not for the testBench
function. For the testBench function, used tbSystemClockGen
tbSystemClockGen :: Signal System Bool -> Clock System Source Source #
Clock generator for the System
clock domain.
NB: can be used in the testBench function
Example
topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)
topEntity = concat
testBench :: Signal System Bool
testBench = done
where
testInput = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)
expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)
done = exposeClockReset (expectedOutput (topEntity $ testInput)) clk rst
clk = tbSystemClockGen
(not <$> done)
rst = systemResetGen
systemResetGen :: Reset System Asynchronous Source #
Reset generator for the System
clock domain.
NB: should only be used for simulation or the testBench function.
Example
topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)
topEntity = concat
testBench :: Signal System Bool
testBench = done
where
testInput = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)
expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)
done = exposeClockReset (expectedOutput (topEntity $ testInput)) clk rst
clk = tbSystemClockGen (not <$> done)
rst = systemResetGen
Boolean connectives
Product/Signal isomorphism
Isomorphism between a Signal
of a product type (e.g. a tuple) and a
product type of Signal'
s.
Instances of Bundle
must satisfy the following laws:
bundle
.unbundle
=id
unbundle
.bundle
=id
By default, bundle
and unbundle
, are defined as the identity, that is,
writing:
data D = A | B instance Bundle D
is the same as:
data D = A | B instance Bundle D where typeUnbundled'
clk D =Signal'
clk Dbundle
_ s = sunbundle
_ s = s
bundle :: Unbundled domain a -> Signal domain a Source #
Example:
bundle :: (Signal
domain a,Signal
domain b) ->Signal
clk (a,b)
However:
bundle ::Signal
domainBit
->Signal
domainBit
bundle :: Signal domain a ~ Unbundled domain a => Unbundled domain a -> Signal domain a Source #
Example:
bundle :: (Signal
domain a,Signal
domain b) ->Signal
clk (a,b)
However:
bundle ::Signal
domainBit
->Signal
domainBit
unbundle :: Signal domain a -> Unbundled domain a Source #
Example:
unbundle ::Signal
domain (a,b) -> (Signal
domain a,Signal
domain b)
However:
unbundle ::Signal
domainBit
->Signal
domainBit
unbundle :: Unbundled domain a ~ Signal domain a => Signal domain a -> Unbundled domain a Source #
Instances
Bundle Bool Source # | |
Bundle Double Source # | |
Bundle Float Source # | |
Bundle Int Source # | |
Bundle Integer Source # | |
Bundle () Source # | Note that: bundle :: () -> Signal domain () unbundle :: Signal domain () -> () |
Bundle Bit Source # | |
Bundle (Maybe a) Source # | |
Bundle (BitVector n) Source # | |
Bundle (Index n) Source # | |
Bundle (Unsigned n) Source # | |
Bundle (Signed n) Source # | |
Bundle (Either a b) Source # | |
Bundle (a, b) Source # | |
KnownNat n => Bundle (Vec n a) Source # | |
KnownNat d => Bundle (RTree d a) Source # | |
Bundle (a, b, c) Source # | |
Bundle (Fixed rep int frac) Source # | |
Bundle (a, b, c, d) Source # | |
Bundle (a, b, c, d, e) Source # | |
Bundle (a, b, c, d, e, f) Source # | |
Bundle (a, b, c, d, e, f, g) Source # | |
Bundle (a, b, c, d, e, f, g, h) Source # | |
Simulation functions (not synthesisable)
lazy versions
:: (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b) | Function we want to simulate, whose components potentially have a hidden clock (and reset) |
-> [a] | |
-> [b] |
:: (Bundle a, Bundle b) | |
=> (HiddenClockReset domain gated synchronous => Unbundled domain a -> Unbundled domain b) | Function we want to simulate, whose components potentially have a hidden clock (and reset) |
-> [a] | |
-> [b] |
List <-> Signal conversion (not synthesisable)
:: NFData a | |
=> (HiddenClockReset domain gated synchronous => Signal domain a) |
|
-> [a] |
:: NFData a | |
=> Int | The number of samples we want to see |
-> (HiddenClockReset domain gated synchronous => Signal domain a) |
|
-> [a] |
fromList :: NFData a => [a] -> Signal domain a Source #
Create a Signal
from a list
Every element in the list will correspond to a value of the signal for one clock cycle.
>>>
sampleN 2 (fromList [1,2,3,4,5])
[1,2]
NB: This function is not synthesisable
lazy versions
:: (HiddenClockReset domain gated synchronous => Signal domain a) |
|
-> [a] |
:: Int | |
-> (HiddenClockReset domain gated synchronous => Signal domain a) |
|
-> [a] |
fromList_lazy :: [a] -> Signal domain a Source #
Create a Signal
from a list
Every element in the list will correspond to a value of the signal for one clock cycle.
>>>
sampleN 2 (fromList [1,2,3,4,5])
[1,2]
NB: This function is not synthesisable
QuickCheck combinators
:: Int | The number of cycles we want to test for |
-> (HiddenClockReset domain gated synchronous => Signal domain Bool) |
|
-> Property |
testFor n s
tests the signal s for n cycles.