clash-prelude-0.99.1: CAES Language for Synchronous Hardware - Prelude library

Copyright(C) 2013-2016 University of Twente
2016 Myrtle Software
2017 Google Inc.
LicenseBSD2 (see the file LICENSE)
MaintainerChristiaan Baaij <christiaan.baaij@gmail.com>
Safe HaskellTrustworthy
LanguageHaskell2010
Extensions
  • MonoLocalBinds
  • ScopedTypeVariables
  • GADTs
  • GADTSyntax
  • RebindableSyntax
  • ConstraintKinds
  • DataKinds
  • FlexibleContexts
  • MagicHash
  • RankNTypes
  • ExplicitForAll
  • OverloadedLabels
  • TypeApplications

Clash.Signal

Contents

Description

CλaSH has synchronous Signals 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 Signals 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

Synchronous signals

data Signal (domain :: Domain) a Source #

CλaSH has synchronous Signals 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 Signals 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 # 
Instance details

Methods

fmap :: (a -> b) -> Signal domain a -> Signal domain b #

(<$) :: a -> Signal domain b -> Signal domain a #

Applicative (Signal domain) Source # 
Instance details

Methods

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 "foldr f z s":

  • The function f should be lazy in its second argument.
  • The z element will never be used.
Instance details

Methods

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 #

sum :: Num a => Signal domain a -> a #

product :: Num a => Signal domain a -> a #

Traversable (Signal domain) Source # 
Instance details

Methods

traverse :: Applicative f => (a -> f b) -> Signal domain a -> f (Signal domain b) #

sequenceA :: Applicative f => Signal domain (f a) -> f (Signal domain a) #

mapM :: Monad m => (a -> m b) -> Signal domain a -> m (Signal domain b) #

sequence :: Monad m => Signal domain (m a) -> m (Signal domain a) #

Fractional a => Fractional (Signal domain a) Source # 
Instance details

Methods

(/) :: Signal domain a -> Signal domain a -> Signal domain a #

recip :: Signal domain a -> Signal domain a #

fromRational :: Rational -> Signal domain a #

Num a => Num (Signal domain a) Source # 
Instance details

Methods

(+) :: 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 # 
Instance details

Methods

showsPrec :: Int -> Signal domain a -> ShowS #

show :: Signal domain a -> String #

showList :: [Signal domain a] -> ShowS #

Lift a => Lift (Signal domain a) Source # 
Instance details

Methods

lift :: Signal domain a -> Q Exp #

Default a => Default (Signal domain a) Source # 
Instance details

Methods

def :: Signal domain a

Arbitrary a => Arbitrary (Signal domain a) Source # 
Instance details

Methods

arbitrary :: Gen (Signal domain a)

shrink :: Signal domain a -> [Signal domain a]

CoArbitrary a => CoArbitrary (Signal domain a) Source # 
Instance details

Methods

coarbitrary :: Signal domain a -> Gen b -> Gen b

data Domain Source #

A domain with a name (Symbol) and a clock period (Nat) in ps

Constructors

Dom 

type System = Dom "system" 10000 Source #

A clock (and reset) domain with clocks running at 100 MHz

Clock

data Clock (domain :: Domain) (gated :: ClockKind) Source #

A clock signal belonging to a domain

Instances
Show (Clock domain gated) Source # 
Instance details

Methods

showsPrec :: Int -> Clock domain gated -> ShowS #

show :: Clock domain gated -> String #

showList :: [Clock domain gated] -> ShowS #

data ClockKind Source #

Distinction between gated and ungated clocks

Constructors

Source

A clock signal coming straight from the clock source

Gated

A clock signal that has been gated

Instances
Eq ClockKind Source # 
Instance details
Ord ClockKind Source # 
Instance details
Show ClockKind Source # 
Instance details
Generic ClockKind Source # 
Instance details

Associated Types

type Rep ClockKind :: * -> * #

NFData ClockKind Source # 
Instance details

Methods

rnf :: ClockKind -> () #

type Rep ClockKind Source # 
Instance details
type Rep ClockKind = D1 (MetaData "ClockKind" "Clash.Signal.Internal" "clash-prelude-0.99.1-inplace" False) (C1 (MetaCons "Source" PrefixI False) (U1 :: * -> *) :+: C1 (MetaCons "Gated" PrefixI False) (U1 :: * -> *))

Reset

data Reset (domain :: Domain) (synchronous :: ResetKind) Source #

A reset signal belonging to a domain.

The underlying representation of resets is Bool. Note that all components in the clash-prelude package have an active-high reset port, i.e., the component is reset when the reset port is True.

data ResetKind Source #

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]

Constructors

Synchronous

Components with a synchronous reset port produce the reset value when:

  • The reset is asserted during the active flank of the clock to which the component is synchronized.
Asynchronous

Components with an asynchronous reset port produce the reset value when:

  • Immediately when the reset is asserted.
Instances
Eq ResetKind Source # 
Instance details
Ord ResetKind Source # 
Instance details
Show ResetKind Source # 
Instance details
Generic ResetKind Source # 
Instance details

Associated Types

type Rep ResetKind :: * -> * #

NFData ResetKind Source # 
Instance details

Methods

rnf :: ResetKind -> () #

type Rep ResetKind Source # 
Instance details
type Rep ResetKind = D1 (MetaData "ResetKind" "Clash.Signal.Internal" "clash-prelude-0.99.1-inplace" False) (C1 (MetaCons "Synchronous" PrefixI False) (U1 :: * -> *) :+: C1 (MetaCons "Asynchronous" PrefixI False) (U1 :: * -> *))

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

Expand
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

Expand
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 = f hasClock 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)
  in  exposeClockReset 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)
  in  withClockReset 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

Click here to read more about hidden clocks and resets

hideClock Source #

Arguments

:: 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.

Click here to read more about hidden clocks and resets

exposeClock Source #

Arguments

:: (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

Click here to read more about hidden clocks and resets

withClock Source #

Arguments

:: Clock domain gated

The Clock we want to connect

-> (HiddenClock domain gated => r)

The function with a hidden Clock argument

-> r 

Connect an explicit Clock to a function with a hidden Clock argument.

withClock = flip exposeClock

hasClock :: HiddenClock domain gated => Clock domain gated Source #

Connect a hidden Clock to an argument where a normal Clock argument was expected.

Click here to read more about hidden clocks and resets

Hidden reset

type HiddenReset domain synchronous = Hidden "rst" (Reset domain synchronous) Source #

A constraint that indicates the component needs a Reset

Click here to read more about hidden clocks and resets

hideReset Source #

Arguments

:: 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.

Click here to read more about hidden clocks and resets

exposeReset Source #

Arguments

:: (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

Click here to read more about hidden clocks and resets

withReset Source #

Arguments

:: Reset domain synchronous

The Reset we want to connect

-> (HiddenReset domain synchronous => r)

The function with a hidden Reset argument

-> r 

Connect an explicit Reset to a function with a hidden Reset argument.

withReset = flip exposeReset

Click here to read more about hidden clocks and resets

hasReset :: HiddenReset domain synchronous => Reset domain synchronous Source #

Connect a hidden Reset to an argument where a normal Reset argument was expected.

Click here to read more about hidden clocks and resets

Hidden clock and reset

type HiddenClockReset domain gated synchronous = (HiddenClock domain gated, HiddenReset domain synchronous) Source #

A constraint that indicates the component needs a Clock and Reset

Click here to read more about hidden clocks and resets

hideClockReset Source #

Arguments

:: HiddenClockReset domain gated synchronous 
=> (Clock domain gated -> Reset domain synchronous -> r)

Component whose clock and reset argument you want to hide

-> r 

exposeClockReset Source #

Arguments

:: (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

Expand
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

withClockReset Source #

Arguments

:: Clock domain gated

The Clock we want to connect

-> Reset domain synchronous

The Reset we want to connect

-> (HiddenClockReset domain gated synchronous => r)

The function with a hidden Clock and hidden Reset argument

-> r 

Connect an explicit Clock and Reset to a function with a hidden Clock and Reset argument.

Click here to read more about hidden clocks and resets

type SystemClockReset = HiddenClockReset System Source Asynchronous Source #

A constraint that indicates the component needs a Clock and a Reset belonging to the System domain.

Click here to read more about hidden clocks and resets

Basic circuit functions

delay Source #

Arguments

:: (HiddenClock domain gated, HasCallStack) 
=> Signal domain a

Signal to delay

-> Signal domain a 

delay s delays the values in Signal s for once cycle, the value at time 0 is undefined.

>>> printX (sampleN 3 (delay (fromList [1,2,3,4])))
[X,1,2]

register infixr 3 Source #

Arguments

:: (HiddenClockReset domain gated synchronous, HasCallStack) 
=> a

Reset value

register has an active-high Reset, meaning that register outputs the reset value when the reset value becomes True

-> Signal domain a 
-> Signal domain a 

register i s delays the values in Signal s for one cycle, and sets the value at time 0 to i

>>> sampleN 3 (register 8 (fromList [1,2,3,4]))
[8,1,2]

regMaybe infixr 3 Source #

Arguments

:: (HiddenClockReset domain gated synchronous, HasCallStack) 
=> a

Reset value

regMaybe has an active-high Reset, meaning that regMaybe outputs the reset value when the reset value becomes True

-> 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]

regEn Source #

Arguments

:: (HiddenClockReset domain gated synchronous, HasCallStack) 
=> a

Reset value

regEn has an active-high Reset, meaning that regEn outputs the reset value when the reset value becomes True

-> Signal domain Bool 
-> Signal domain a 
-> Signal domain a 

Version of register that only updates its content when its second argument is asserted. So given:

oscillate = register False (not <$> oscillate)
count     = regEn 0 oscillate (count + 1)

We get:

>>> sampleN 8 oscillate
[False,True,False,True,False,True,False,True]
>>> sampleN 8 count
[0,0,1,1,2,2,3,3]

mux :: Applicative f => f Bool -> f a -> f a -> f a Source #

The above type is a generalisation for:

mux :: Signal Bool -> Signal a -> Signal a -> Signal a

A multiplexer. Given "mux b t f", output t when b is True, and f when b is False.

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

Expand
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

Expand
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

Expand
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

Expand
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

(.&&.) :: Applicative f => f Bool -> f Bool -> f Bool infixr 3 Source #

The above type is a generalisation for:

(.&&.) :: Signal Bool -> Signal Bool -> Signal Bool

It is a version of (&&) that returns a Signal of Bool

(.||.) :: Applicative f => f Bool -> f Bool -> f Bool infixr 2 Source #

The above type is a generalisation for:

(.||.) :: Signal Bool -> Signal Bool -> Signal Bool

It is a version of (||) that returns a Signal of Bool

Product/Signal isomorphism

class Bundle a where Source #

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
  type Unbundled' clk D = Signal' clk D
  bundle   _ s = s
  unbundle _ s = s

Associated Types

type Unbundled (domain :: Domain) a = res | res -> domain a Source #

Methods

bundle :: Unbundled domain a -> Signal domain a Source #

Example:

bundle :: (Signal domain a, Signal domain b) -> Signal clk (a,b)

However:

bundle :: Signal domain Bit -> Signal domain Bit

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 domain Bit -> Signal domain Bit

unbundle :: Signal domain a -> Unbundled domain a Source #

Example:

unbundle :: Signal domain (a,b) -> (Signal domain a, Signal domain b)

However:

unbundle :: Signal domain Bit -> Signal domain Bit

unbundle :: Unbundled domain a ~ Signal domain a => Signal domain a -> Unbundled domain a Source #

Example:

unbundle :: Signal domain (a,b) -> (Signal domain a, Signal domain b)

However:

unbundle :: Signal domain Bit -> Signal domain Bit
Instances
Bundle Bool Source # 
Instance details

Associated Types

type Unbundled domain Bool = (res :: *) Source #

Methods

bundle :: Unbundled domain Bool -> Signal domain Bool Source #

unbundle :: Signal domain Bool -> Unbundled domain Bool Source #

Bundle Double Source # 
Instance details

Associated Types

type Unbundled domain Double = (res :: *) Source #

Methods

bundle :: Unbundled domain Double -> Signal domain Double Source #

unbundle :: Signal domain Double -> Unbundled domain Double Source #

Bundle Float Source # 
Instance details

Associated Types

type Unbundled domain Float = (res :: *) Source #

Methods

bundle :: Unbundled domain Float -> Signal domain Float Source #

unbundle :: Signal domain Float -> Unbundled domain Float Source #

Bundle Int Source # 
Instance details

Associated Types

type Unbundled domain Int = (res :: *) Source #

Methods

bundle :: Unbundled domain Int -> Signal domain Int Source #

unbundle :: Signal domain Int -> Unbundled domain Int Source #

Bundle Integer Source # 
Instance details

Associated Types

type Unbundled domain Integer = (res :: *) Source #

Methods

bundle :: Unbundled domain Integer -> Signal domain Integer Source #

unbundle :: Signal domain Integer -> Unbundled domain Integer Source #

Bundle () Source #

Note that:

bundle   :: () -> Signal domain ()
unbundle :: Signal domain () -> ()
Instance details

Associated Types

type Unbundled domain () = (res :: *) Source #

Methods

bundle :: Unbundled domain () -> Signal domain () Source #

unbundle :: Signal domain () -> Unbundled domain () Source #

Bundle Bit Source # 
Instance details

Associated Types

type Unbundled domain Bit = (res :: *) Source #

Methods

bundle :: Unbundled domain Bit -> Signal domain Bit Source #

unbundle :: Signal domain Bit -> Unbundled domain Bit Source #

Bundle (Maybe a) Source # 
Instance details

Associated Types

type Unbundled domain (Maybe a) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Maybe a) -> Signal domain (Maybe a) Source #

unbundle :: Signal domain (Maybe a) -> Unbundled domain (Maybe a) Source #

Bundle (BitVector n) Source # 
Instance details

Associated Types

type Unbundled domain (BitVector n) = (res :: *) Source #

Methods

bundle :: Unbundled domain (BitVector n) -> Signal domain (BitVector n) Source #

unbundle :: Signal domain (BitVector n) -> Unbundled domain (BitVector n) Source #

Bundle (Index n) Source # 
Instance details

Associated Types

type Unbundled domain (Index n) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Index n) -> Signal domain (Index n) Source #

unbundle :: Signal domain (Index n) -> Unbundled domain (Index n) Source #

Bundle (Unsigned n) Source # 
Instance details

Associated Types

type Unbundled domain (Unsigned n) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Unsigned n) -> Signal domain (Unsigned n) Source #

unbundle :: Signal domain (Unsigned n) -> Unbundled domain (Unsigned n) Source #

Bundle (Signed n) Source # 
Instance details

Associated Types

type Unbundled domain (Signed n) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Signed n) -> Signal domain (Signed n) Source #

unbundle :: Signal domain (Signed n) -> Unbundled domain (Signed n) Source #

Bundle (Either a b) Source # 
Instance details

Associated Types

type Unbundled domain (Either a b) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Either a b) -> Signal domain (Either a b) Source #

unbundle :: Signal domain (Either a b) -> Unbundled domain (Either a b) Source #

Bundle (a, b) Source # 
Instance details

Associated Types

type Unbundled domain (a, b) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b) -> Signal domain (a, b) Source #

unbundle :: Signal domain (a, b) -> Unbundled domain (a, b) Source #

KnownNat n => Bundle (Vec n a) Source # 
Instance details

Associated Types

type Unbundled domain (Vec n a) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Vec n a) -> Signal domain (Vec n a) Source #

unbundle :: Signal domain (Vec n a) -> Unbundled domain (Vec n a) Source #

KnownNat d => Bundle (RTree d a) Source # 
Instance details

Associated Types

type Unbundled domain (RTree d a) = (res :: *) Source #

Methods

bundle :: Unbundled domain (RTree d a) -> Signal domain (RTree d a) Source #

unbundle :: Signal domain (RTree d a) -> Unbundled domain (RTree d a) Source #

Bundle (a, b, c) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c) -> Signal domain (a, b, c) Source #

unbundle :: Signal domain (a, b, c) -> Unbundled domain (a, b, c) Source #

Bundle (Fixed rep int frac) Source # 
Instance details

Associated Types

type Unbundled domain (Fixed rep int frac) = (res :: *) Source #

Methods

bundle :: Unbundled domain (Fixed rep int frac) -> Signal domain (Fixed rep int frac) Source #

unbundle :: Signal domain (Fixed rep int frac) -> Unbundled domain (Fixed rep int frac) Source #

Bundle (a, b, c, d) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c, d) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c, d) -> Signal domain (a, b, c, d) Source #

unbundle :: Signal domain (a, b, c, d) -> Unbundled domain (a, b, c, d) Source #

Bundle (a, b, c, d, e) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c, d, e) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c, d, e) -> Signal domain (a, b, c, d, e) Source #

unbundle :: Signal domain (a, b, c, d, e) -> Unbundled domain (a, b, c, d, e) Source #

Bundle (a, b, c, d, e, f) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c, d, e, f) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c, d, e, f) -> Signal domain (a, b, c, d, e, f) Source #

unbundle :: Signal domain (a, b, c, d, e, f) -> Unbundled domain (a, b, c, d, e, f) Source #

Bundle (a, b, c, d, e, f, g) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c, d, e, f, g) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c, d, e, f, g) -> Signal domain (a, b, c, d, e, f, g) Source #

unbundle :: Signal domain (a, b, c, d, e, f, g) -> Unbundled domain (a, b, c, d, e, f, g) Source #

Bundle (a, b, c, d, e, f, g, h) Source # 
Instance details

Associated Types

type Unbundled domain (a, b, c, d, e, f, g, h) = (res :: *) Source #

Methods

bundle :: Unbundled domain (a, b, c, d, e, f, g, h) -> Signal domain (a, b, c, d, e, f, g, h) Source #

unbundle :: Signal domain (a, b, c, d, e, f, g, h) -> Unbundled domain (a, b, c, d, e, f, g, h) Source #

Simulation functions (not synthesisable)

simulate Source #

Arguments

:: (NFData a, NFData b) 
=> (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b)

Signal we want to sample, whose source potentially has a hidden clock (and reset)

-> [a] 
-> [b] 

Simulate a (Signal a -> Signal b) function given a list of samples of type a

>>> simulate (register 8) [1, 2, 3]
[8,1,2,3...
...

NB: This function is not synthesisable

simulateB Source #

Arguments

:: (Bundle a, Bundle b, NFData a, NFData 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] 

Simulate a (Unbundled a -> Unbundled b) function given a list of samples of type a

>>> simulateB (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]
[(8,8),(1,1),(2,2),(3,3)...
...

NB: This function is not synthesisable

lazy versions

simulate_lazy Source #

Arguments

:: (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] 

Lazily simulate a (Signal a -> Signal b) function given a list of samples of type a

>>> simulate (register 8) [1, 2, 3]
[8,1,2,3...
...

NB: This function is not synthesisable

simulateB_lazy Source #

Arguments

:: (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] 

Lazily simulate a (Unbundled a -> Unbundled b) function given a list of samples of type a

>>> simulateB (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]
[(8,8),(1,1),(2,2),(3,3)...
...

NB: This function is not synthesisable

List <-> Signal conversion (not synthesisable)

sample Source #

Arguments

:: NFData a 
=> (HiddenClockReset domain gated synchronous => Signal domain a)

Signal we want to sample, whose source potentially has a hidden clock (and reset)

-> [a] 

Get an infinite list of samples from a Signal

The elements in the list correspond to the values of the Signal at consecutive clock cycles

sample s == [s0, s1, s2, s3, ...

NB: This function is not synthesisable

sampleN Source #

Arguments

:: NFData a 
=> Int

The number of samples we want to see

-> (HiddenClockReset domain gated synchronous => Signal domain a)

Signal we want to sample, whose source potentially has a hidden clock (and reset)

-> [a] 

Get a list of n samples from a Signal

The elements in the list correspond to the values of the Signal at consecutive clock cycles

sampleN 3 s == [s0, s1, s2]

NB: This function is not synthesisable

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

sample_lazy Source #

Arguments

:: (HiddenClockReset domain gated synchronous => Signal domain a)

Signal we want to sample, whose source potentially has a hidden clock (and reset)

-> [a] 

Lazily get an infinite list of samples from a Signal

The elements in the list correspond to the values of the Signal at consecutive clock cycles

sample s == [s0, s1, s2, s3, ...

NB: This function is not synthesisable

sampleN_lazy Source #

Arguments

:: Int 
-> (HiddenClockReset domain gated synchronous => Signal domain a)

Signal we want to sample, whose source potentially has a hidden clock (and reset)

-> [a] 

Lazily get a list of n samples from a Signal

The elements in the list correspond to the values of the Signal at consecutive clock cycles

sampleN 3 s == [s0, s1, s2]

NB: This function is not synthesisable

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

testFor Source #

Arguments

:: Int

The number of cycles we want to test for

-> (HiddenClockReset domain gated synchronous => Signal domain Bool)

Signal we want to evaluate, whose source potentially has a hidden clock (and reset)

-> Property 

testFor n s tests the signal s for n cycles.

Type classes

Eq-like

(.==.) :: (Eq a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(.==.) :: Eq a => Signal a -> Signal a -> Signal Bool

It is a version of (==) that returns a Signal of Bool

(./=.) :: (Eq a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(./=.) :: Eq a => Signal a -> Signal a -> Signal Bool

It is a version of (/=) that returns a Signal of Bool

Ord-like

(.<.) :: (Ord a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(.<.) :: Ord a => Signal a -> Signal a -> Signal Bool

It is a version of (<) that returns a Signal of Bool

(.<=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(.<=.) :: Ord a => Signal a -> Signal a -> Signal Bool

It is a version of (<=) that returns a Signal of Bool

(.>=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(.>=.) :: Ord a => Signal a -> Signal a -> Signal Bool

It is a version of (>=) that returns a Signal of Bool

(.>.) :: (Ord a, Applicative f) => f a -> f a -> f Bool infix 4 Source #

The above type is a generalisation for:

(.>.) :: Ord a => Signal a -> Signal a -> Signal Bool

It is a version of (>) that returns a Signal of Bool