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

Clash.Signal.Internal

Description

Synopsis

# Datatypes

data Domain Source #

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

Constructors

 Dom FieldsdomainName :: Symbol clkPeriod :: Nat

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!

Constructors

 a :- (Signal domain a) infixr 5 The constructor, (:-), is not synthesisable.
Instances
 Functor (Signal domain) Source # Instance detailsMethodsfmap :: (a -> b) -> Signal domain a -> Signal domain b #(<$) :: a -> Signal domain b -> Signal domain a # Applicative (Signal domain) Source # Instance detailsMethodspure :: 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 synthesisableNB: In "foldr f z s":The function f should be lazy in its second argument.The z element will never be used. Instance detailsMethodsfold :: 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 detailsMethodstraverse :: 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 detailsMethods(/) :: 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 detailsMethods(+) :: 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 detailsMethodsshowsPrec :: Int -> Signal domain a -> ShowS #show :: Signal domain a -> String #showList :: [Signal domain a] -> ShowS # Lift a => Lift (Signal domain a) Source # Instance detailsMethodslift :: Signal domain a -> Q Exp # Arbitrary a => Arbitrary (Signal domain a) Source # Instance detailsMethodsarbitrary :: Gen (Signal domain a) #shrink :: Signal domain a -> [Signal domain a] # CoArbitrary a => CoArbitrary (Signal domain a) Source # Instance detailsMethodscoarbitrary :: Signal domain a -> Gen b -> Gen b # Default a => Default (Signal domain a) Source # Instance detailsMethodsdef :: Signal domain a # # Clocks data Clock (domain :: Domain) (gated :: ClockKind) where Source # A clock signal belonging to a domain Constructors  Clock :: domain ~ Dom name period => SSymbol name -> SNat period -> Clock domain Source GatedClock :: domain ~ Dom name period => SSymbol name -> SNat period -> Signal domain Bool -> Clock domain Gated Instances  Show (Clock domain gated) Source # Instance detailsMethodsshowsPrec :: 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  Source # Instance detailsMethods Source # Instance detailsMethods Source # Instance detailsMethodsshowList :: [ClockKind] -> ShowS # Source # Instance detailsAssociated Typestype Rep ClockKind :: * -> * # Methodsto :: Rep ClockKind x -> ClockKind # Source # Instance detailsMethodsrnf :: ClockKind -> () # type Rep ClockKind Source # Instance detailstype Rep ClockKind = D1 (MetaData "ClockKind" "Clash.Signal.Internal" "clash-prelude-0.99.3-inplace" False) (C1 (MetaCons "Source" PrefixI False) (U1 :: * -> *) :+: C1 (MetaCons "Gated" PrefixI False) (U1 :: * -> *)) clockPeriod :: Num a => Clock domain gated -> a Source # Get the clock period of a Clock (in ps) as a Num clockEnable :: Clock domain gated -> Maybe (Signal domain Bool) Source # If the clock is gated, return Just the enable signal, Nothing otherwise ## Clock gating clockGate :: Clock domain gated -> Signal domain Bool -> Clock domain Gated Source # Clock gating primitive # Resets data Reset (domain :: Domain) (synchronous :: ResetKind) where 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. Constructors  Sync :: Signal domain Bool -> Reset domain Synchronous Async :: Signal domain Bool -> Reset domain Asynchronous 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  Source # Instance detailsMethods Source # Instance detailsMethods Source # Instance detailsMethodsshowList :: [ResetKind] -> ShowS # Source # Instance detailsAssociated Typestype Rep ResetKind :: * -> * # Methodsto :: Rep ResetKind x -> ResetKind # Source # Instance detailsMethodsrnf :: ResetKind -> () # type Rep ResetKind Source # Instance detailstype Rep ResetKind = D1 (MetaData "ResetKind" "Clash.Signal.Internal" "clash-prelude-0.99.3-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. # Basic circuits delay# :: HasCallStack => Clock domain gated -> Signal domain a -> Signal domain a Source # register# :: HasCallStack => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain a Source # 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


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.

# 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

# Simulation functions (not synthesisable)

simulate :: (NFData a, NFData b) => (Signal domain1 a -> Signal domain2 b) -> [a] -> [b] Source #

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

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


NB: This function is not synthesisable

## lazy version

simulate_lazy :: (Signal domain1 a -> Signal domain2 b) -> [a] -> [b] Source #

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

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


NB: This function is not synthesisable

# List <-> Signal conversion (not synthesisable)

sample :: (Foldable f, NFData a) => f a -> [a] Source #

The above type is a generalisation for:

sample :: Signal a -> [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 :: (Foldable f, NFData a) => Int -> f a -> [a] Source #

The above type is a generalisation for:

sampleN :: Int -> Signal a -> [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 :: Foldable f => f a -> [a] Source #

The above type is a generalisation for:

sample :: Signal a -> [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_lazy :: Foldable f => Int -> f a -> [a] Source #

The above type is a generalisation for:

sampleN :: Int -> Signal a -> [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_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 :: Foldable f => Int -> f Bool -> Property Source #

The above type is a generalisation for:

testFor :: Int -> Signal Bool -> 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

## Functor

mapSignal# :: (a -> b) -> Signal domain a -> Signal domain b Source #

## Applicative

signal# :: a -> Signal domain a Source #

appSignal# :: Signal domain (a -> b) -> Signal domain a -> Signal domain b Source #

## Foldable

foldr# :: (a -> b -> b) -> b -> Signal domain a -> b 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.

## Traversable

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

# EXTREMELY EXPERIMENTAL

joinSignal# :: Signal domain (Signal domain a) -> Signal domain a Source #

WARNING: EXTREMELY EXPERIMENTAL

The circuit semantics of this operation are unclear and/or non-existent. There is a good reason there is no Monad instance for Signal'.

Is currently treated as id by the Clash compiler.