Copyright | (C) 2013-2016 University of Twente 2017 Google Inc. 2019 Myrtle Software Ltd |
---|---|
License | BSD2 (see the file LICENSE) |
Maintainer | Christiaan Baaij <christiaan.baaij@gmail.com> |
Safe Haskell | Unsafe |
Language | Haskell2010 |
Extensions |
|
This module defines the explicitly clocked counterparts of the functions defined in Clash.Prelude.
Synopsis
- mealy :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- mealyB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- moore :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- mooreB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- registerB :: (KnownDomain dom, NFDataX a, Bundle a) => Clock dom -> Reset dom -> Enable dom -> a -> Unbundled dom a -> Unbundled dom a
- dualFlipFlopSynchronizer :: (NFDataX a, KnownDomain dom1, KnownDomain dom2) => Clock dom1 -> Clock dom2 -> Reset dom2 -> Enable dom2 -> a -> Signal dom1 a -> Signal dom2 a
- asyncFIFOSynchronizer :: (KnownDomain wdom, KnownDomain rdom, 2 <= addrSize) => SNat addrSize -> Clock wdom -> Clock rdom -> Reset wdom -> Reset rdom -> Enable wdom -> Enable rdom -> Signal rdom Bool -> Signal wdom (Maybe a) -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)
- asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
- asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
- rom :: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom a
- romPow2 :: (KnownDomain dom, KnownNat n, NFDataX a) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- asyncRomFile :: (KnownNat m, Enum addr) => SNat n -> FilePath -> addr -> BitVector m
- asyncRomFilePow2 :: forall n m. (KnownNat m, KnownNat n) => FilePath -> Unsigned n -> BitVector m
- romFile :: (KnownNat m, Enum addr, KnownDomain dom) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (BitVector m)
- romFilePow2 :: forall dom n m. (KnownNat m, KnownNat n, KnownDomain dom) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- asyncRamPow2 :: forall wdom rdom n a. (KnownNat n, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
- blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- blockRamPow2 :: (KnownDomain dom, HasCallStack, NFDataX a, KnownNat n) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- data ResetStrategy (r :: Bool) where
- blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- blockRamFilePow2 :: forall dom n m. (KnownDomain dom, KnownNat m, KnownNat n, HasCallStack) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- readNew :: (KnownDomain dom, NFDataX a, Eq addr) => Clock dom -> Reset dom -> Enable dom -> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- window :: (KnownNat n, KnownDomain dom, NFDataX a, Default a) => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Vec (n + 1) (Signal dom a)
- windowD :: (KnownNat n, NFDataX a, Default a, KnownDomain dom) => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Vec (n + 1) (Signal dom a)
- isRising :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- isFalling :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- riseEvery :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> SNat n -> Signal dom Bool
- oscillate :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Bool -> SNat n -> Signal dom Bool
- assert :: (KnownDomain dom, Eq a, ShowX a) => Clock dom -> Reset dom -> String -> Signal dom a -> Signal dom a -> Signal dom b -> Signal dom b
- stimuliGenerator :: forall l dom a. (KnownNat l, KnownDomain dom) => Clock dom -> Reset dom -> Vec l a -> Signal dom a
- outputVerifier' :: forall l a dom. (KnownNat l, KnownDomain dom, DomainResetKind dom ~ 'Asynchronous, Eq a, ShowX a) => Clock dom -> Reset dom -> Vec l a -> Signal dom a -> Signal dom Bool
- traceSignal1 :: (BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
- traceVecSignal1 :: (KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
- traceSignal :: forall dom a. (KnownDomain dom, BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
- traceVecSignal :: forall dom a n. (KnownDomain dom, KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
- dumpVCD :: NFDataX a => (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
- module Clash.Explicit.Signal
- module Clash.Explicit.Signal.Delayed
- module Clash.Prelude.DataFlow
- module Clash.Sized.BitVector
- module Clash.Prelude.BitIndex
- module Clash.Prelude.BitReduction
- module Clash.Sized.Signed
- module Clash.Sized.Unsigned
- module Clash.Sized.Index
- module Clash.Sized.Fixed
- module Clash.Sized.Vector
- module Clash.Sized.RTree
- module Clash.Annotations.TopEntity
- class Generic a
- class Generic1 (f :: k -> Type)
- module GHC.TypeLits
- module GHC.TypeLits.Extra
- module Clash.Promoted.Nat
- module Clash.Promoted.Nat.Literals
- module Clash.Promoted.Nat.TH
- module Clash.Promoted.Symbol
- class Lift t where
- module Clash.Class.AutoReg
- module Clash.Class.BitPack
- module Clash.Class.Exp
- module Clash.Class.Num
- module Clash.Class.Resize
- module Control.Applicative
- module Data.Bits
- module Data.Default.Class
- module Clash.XException
- module Clash.NamedTypes
- module Clash.Magic
- module Clash.HaskellPrelude
Creating synchronous sequential circuits
:: (KnownDomain dom, NFDataX s) | |
=> Clock dom |
|
-> Reset dom | |
-> Enable dom | Global enable |
-> (s -> i -> (s, o)) | Transfer function in mealy machine form: |
-> s | Initial state |
-> Signal dom i -> Signal dom o | Synchronous sequential function with input and output matching that of the mealy machine |
Create a synchronous function from a combinational function describing a mealy machine
import qualified Data.List as L macT :: Int -- Current state -> (Int,Int) -- Input -> (Int,Int) -- (Updated state, output) macT s (x,y) = (s',s) where s' = x * y + s mac ::KnownDomain
dom =>Clock
dom ->Reset
dom ->Enable
dom ->Signal
dom (Int, Int) ->Signal
dom Int mac clk rst en =mealy
clk rst en macT 0
>>>
simulate (mac systemClockGen systemResetGen enableGen) [(0,0),(1,1),(2,2),(3,3),(4,4)]
[0,0,1,5,14... ...
Synchronous sequential functions can be composed just like their combinational counterpart:
dualMac ::KnownDomain
dom =>Clock
dom ->Reset
dom ->Enable
dom -> (Signal
dom Int,Signal
dom Int) -> (Signal
dom Int,Signal
dom Int) ->Signal
dom Int dualMac clk rst en (a,b) (x,y) = s1 + s2 where s1 =mealy
clk rst en mac 0 (bundle
(a,x)) s2 =mealy
clk rst en mac 0 (bundle
(b,y))
:: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) | |
=> Clock dom | |
-> Reset dom | |
-> Enable dom | |
-> (s -> i -> (s, o)) | Transfer function in mealy machine form: |
-> s | Initial state |
-> Unbundled dom i -> Unbundled dom o | Synchronous sequential function with input and output matching that of the mealy machine |
A version of mealy
that does automatic Bundle
ing
Given a function f
of type:
f :: Int -> (Bool,Int) -> (Int,(Int,Bool))
When we want to make compositions of f
in g
using mealy
, we have to
write:
g clk rst en a b c = (b1,b2,i2) where (i1,b1) =unbundle
(mealy clk rst en f 0 (bundle
(a,b))) (i2,b2) =unbundle
(mealy clk rst en f 3 (bundle
(c,i1)))
Using mealyB
however we can write:
g clk rst en a b c = (b1,b2,i2) where (i1,b1) =mealyB
clk rst en f 0 (a,b) (i2,b2) =mealyB
clk rst en f 3 (c,i1)
:: (KnownDomain dom, NFDataX s) | |
=> Clock dom |
|
-> Reset dom | |
-> Enable dom | |
-> (s -> i -> s) | Transfer function in moore machine form: |
-> (s -> o) | Output function in moore machine form: |
-> s | Initial state |
-> Signal dom i -> Signal dom o | Synchronous sequential function with input and output matching that of the moore machine |
Create a synchronous function from a combinational function describing a moore machine
macT :: Int -- Current state -> (Int,Int) -- Input -> (Int,Int) -- Updated state macT s (x,y) = x * y + s mac ::KnownDomain
dom =>Clock
dom ->Reset
dom ->Enable
dom ->Signal
dom (Int, Int) ->Signal
dom Int mac clk rst en =moore
clk rst en macT id 0
>>>
simulate (mac systemClockGen systemResetGen enableGen) [(0,0),(1,1),(2,2),(3,3),(4,4)]
[0,0,1,5,14... ...
Synchronous sequential functions can be composed just like their combinational counterpart:
dualMac ::KnownDomain
dom =>Clock
dom ->Reset
dom ->Enable
dom -> (Signal
dom Int,Signal
dom Int) -> (Signal
dom Int,Signal
dom Int) ->Signal
dom Int dualMac clk rst en (a,b) (x,y) = s1 + s2 where s1 =moore
clk rst en mac id 0 (bundle
(a,x)) s2 =moore
clk rst en mac id 0 (bundle
(b,y))
:: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) | |
=> Clock dom | |
-> Reset dom | |
-> Enable dom | |
-> (s -> i -> s) | Transfer function in moore machine form:
|
-> (s -> o) | Output function in moore machine form:
|
-> s | Initial state |
-> Unbundled dom i -> Unbundled dom o | Synchronous sequential function with input and output matching that of the moore machine |
A version of moore
that does automatic Bundle
ing
Given a functions t
and o
of types:
t :: Int -> (Bool, Int) -> Int o :: Int -> (Int, Bool)
When we want to make compositions of t
and o
in g
using moore
, we have to
write:
g clk rst en a b c = (b1,b2,i2) where (i1,b1) =unbundle
(moore clk rst en t o 0 (bundle
(a,b))) (i2,b2) =unbundle
(moore clk rst en t o 3 (bundle
(c,i1)))
Using mooreB
however we can write:
g clk rst en a b c = (b1,b2,i2) where (i1,b1) =mooreB
clk rst en t o 0 (a,b) (i2,b2) =mooreB
clk rst en t o 3 (c,i1)
registerB :: (KnownDomain dom, NFDataX a, Bundle a) => Clock dom -> Reset dom -> Enable dom -> a -> Unbundled dom a -> Unbundled dom a Source #
Create a register
function for product-type like signals (e.g.
(
)Signal
a, Signal
b)
rP :: Clock dom -> Reset dom -> Enable dom -> (Signal
dom Int,Signal
dom Int) -> (Signal
dom Int,Signal
dom Int) rP clk rst en =registerB
clk rst en (8,8)
>>>
simulateB (rP systemClockGen systemResetGen enableGen) [(1,1),(1,1),(2,2),(3,3)] :: [(Int,Int)]
[(8,8),(8,8),(1,1),(2,2),(3,3)... ...
Synchronizer circuits for safe clock domain crossings
dualFlipFlopSynchronizer Source #
:: (NFDataX a, KnownDomain dom1, KnownDomain dom2) | |
=> Clock dom1 |
|
-> Clock dom2 |
|
-> Reset dom2 |
|
-> Enable dom2 |
|
-> a | Initial value of the two synchronization registers |
-> Signal dom1 a | Incoming data |
-> Signal dom2 a | Outgoing, synchronized, data |
Synchronizer based on two sequentially connected flip-flops.
- NB: This synchronizer can be used for bit-synchronization.
NB: Although this synchronizer does reduce metastability, it does not guarantee the proper synchronization of a whole word. For example, given that the output is sampled twice as fast as the input is running, and we have two samples in the input stream that look like:
[0111,1000]
But the circuit driving the input stream has a longer propagation delay on msb compared to the lsbs. What can happen is an output stream that looks like this:
[0111,0111,0000,1000]
Where the level-change of the msb was not captured, but the level change of the lsbs were.
If you want to have safe word-synchronization use
asyncFIFOSynchronizer
.
asyncFIFOSynchronizer Source #
:: (KnownDomain wdom, KnownDomain rdom, 2 <= addrSize) | |
=> SNat addrSize | Size of the internally used addresses, the FIFO contains |
-> Clock wdom |
|
-> Clock rdom |
|
-> Reset wdom | |
-> Reset rdom | |
-> Enable wdom | |
-> Enable rdom | |
-> Signal rdom Bool | Read request |
-> Signal wdom (Maybe a) | Element to insert |
-> (Signal rdom a, Signal rdom Bool, Signal wdom Bool) | (Oldest element in the FIFO, |
Synchronizer implemented as a FIFO around an asynchronous RAM. Based on the design described in Clash.Tutorial, which is itself based on the design described in http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf.
NB: This synchronizer can be used for word-synchronization.
ROMs
:: (KnownNat n, Enum addr) | |
=> Vec n a | ROM content NB: must be a constant |
-> addr | Read address |
-> a | The value of the ROM at address |
An asynchronous/combinational ROM with space for n
elements
Additional helpful information:
- See Clash.Sized.Fixed and Clash.Prelude.BlockRam for ideas on how to use ROMs and RAMs
:: KnownNat n | |
=> Vec (2 ^ n) a | ROM content NB: must be a constant |
-> Unsigned n | Read address |
-> a | The value of the ROM at address |
An asynchronous/combinational ROM with space for 2^n
elements
Additional helpful information:
- See Clash.Sized.Fixed and Clash.Prelude.BlockRam for ideas on how to use ROMs and RAMs
:: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> Vec n a | ROM content NB: must be a constant |
-> Signal dom addr | Read address |
-> Signal dom a | The value of the ROM at address |
A ROM with a synchronous read port, with space for n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
Additional helpful information:
- See Clash.Sized.Fixed and Clash.Explicit.BlockRam for ideas on how to use ROMs and RAMs
:: (KnownDomain dom, KnownNat n, NFDataX a) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> Vec (2 ^ n) a | ROM content NB: must be a constant |
-> Signal dom (Unsigned n) | Read address |
-> Signal dom a | The value of the ROM at address |
A ROM with a synchronous read port, with space for 2^n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
Additional helpful information:
- See Clash.Sized.Fixed and Clash.Explicit.BlockRam for ideas on how to use ROMs and RAMs
ROMs initialized with a data file
:: (KnownNat m, Enum addr) | |
=> SNat n | Size of the ROM |
-> FilePath | File describing the content of the ROM |
-> addr | Read address |
-> BitVector m | The value of the ROM at address |
An asynchronous/combinational ROM with space for n
elements
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Prelude.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
- See Clash.Sized.Fixed for ideas on how to create your own data files.
When you notice that
asyncRomFile
is significantly slowing down your simulation, give it a monomorphic type signature. So instead of leaving the type to be inferred:myRomData = asyncRomFile d512 "memory.bin"
or giving it a polymorphic type signature:
myRomData :: Enum addr => addr -> BitVector 16 myRomData = asyncRomFile d512 "memory.bin"
you should give it a monomorphic type signature:
myRomData :: Unsigned 9 -> BitVector 16 myRomData = asyncRomFile d512 "memory.bin"
:: forall n m. (KnownNat m, KnownNat n) | |
=> FilePath | File describing the content of the ROM |
-> Unsigned n | Read address |
-> BitVector m | The value of the ROM at address |
An asynchronous/combinational ROM with space for 2^n
elements
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Prelude.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
- See Clash.Sized.Fixed for ideas on how to create your own data files.
When you notice that
asyncRomFilePow2
is significantly slowing down your simulation, give it a monomorphic type signature. So instead of leaving the type to be inferred:myRomData = asyncRomFilePow2 "memory.bin"
you should give it a monomorphic type signature:
myRomData :: Unsigned 9 -> BitVector 16 myRomData = asyncRomFilePow2 "memory.bin"
:: (KnownNat m, Enum addr, KnownDomain dom) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> SNat n | Size of the ROM |
-> FilePath | File describing the content of the ROM |
-> Signal dom addr | Read address |
-> Signal dom (BitVector m) | The value of the ROM at address |
A ROM with a synchronous read port, with space for n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Explicit.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
- See Clash.Sized.Fixed for ideas on how to create your own data files.
:: forall dom n m. (KnownNat m, KnownNat n, KnownDomain dom) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> FilePath | File describing the content of the ROM |
-> Signal dom (Unsigned n) | Read address |
-> Signal dom (BitVector m) | The value of the ROM at address |
A ROM with a synchronous read port, with space for 2^n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Explicit.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
- See Clash.Sized.Fixed for ideas on how to create your own data files.
RAM primitives with a combinational read port
:: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom) | |
=> Clock wdom |
|
-> Clock rdom |
|
-> Enable wdom | Global enable |
-> SNat n | Size |
-> Signal rdom addr | Read address |
-> Signal wdom (Maybe (addr, a)) | (write address |
-> Signal rdom a | Value of the |
Create a RAM with space for n
elements
- NB: Initial content of the RAM is
undefined
Additional helpful information:
- See Clash.Explicit.BlockRam for more information on how to use a RAM.
:: forall wdom rdom n a. (KnownNat n, HasCallStack, KnownDomain wdom, KnownDomain rdom) | |
=> Clock wdom |
|
-> Clock rdom |
|
-> Enable wdom | Global enable |
-> Signal rdom (Unsigned n) | Read address |
-> Signal wdom (Maybe (Unsigned n, a)) | (write address |
-> Signal rdom a | Value of the |
Create a RAM with space for 2^n
elements
- NB: Initial content of the RAM is
undefined
Additional helpful information:
- See Clash.Prelude.BlockRam for more information on how to use a RAM.
BlockRAM primitives
:: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> Vec n a | Initial content of the BRAM, also determines the size, NB: MUST be a constant. |
-> Signal dom addr | Read address |
-> Signal dom (Maybe (addr, a)) | (write address |
-> Signal dom a | Value of the |
Create a blockRAM with space for n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
bram40 ::Clock
dom ->Enable
dom ->Signal
dom (Unsigned
6) ->Signal
dom (Maybe (Unsigned
6,Bit
)) ->Signal
domBit
bram40 clk en =blockRam
clk en (replicate
d40 1)
Additional helpful information:
- See Clash.Explicit.BlockRam for more information on how to use a Block RAM.
- Use the adapter
readNew
for obtaining write-before-read semantics like this:
.readNew
clk rst (blockRam
clk inits) rd wrM
:: (KnownDomain dom, HasCallStack, NFDataX a, KnownNat n) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> Vec (2 ^ n) a | Initial content of the BRAM, also
determines the size, NB: MUST be a constant. |
-> Signal dom (Unsigned n) | Read address |
-> Signal dom (Maybe (Unsigned n, a)) | (Write address |
-> Signal dom a | Value of the |
Create a blockRAM with space for 2^n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
bram32 ::Clock
dom ->Enable
dom ->Signal
dom (Unsigned
5) ->Signal
dom (Maybe (Unsigned
5,Bit
)) ->Signal
domBit
bram32 clk en =blockRamPow2
clk en (replicate
d32 1)
Additional helpful information:
- See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
- Use the adapter
readNew
for obtaining write-before-read semantics like this:
.readNew
clk rst (blockRamPow2
clk inits) rd wrM
:: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) | |
=> Clock dom |
|
-> Reset dom |
|
-> Enable dom | Global enable |
-> ResetStrategy r | Whether to clear BRAM on asserted reset ( |
-> SNat n | Number of elements in BRAM |
-> (Index n -> a) | If applicable (see first argument), reset BRAM using this function. |
-> Signal dom addr | Read address |
-> Signal dom (Maybe (addr, a)) | (write address |
-> Signal dom a | Value of the |
Version of blockram that has no default values set. May be cleared to a arbitrary state using a reset function.
:: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) | |
=> Clock dom |
|
-> Reset dom |
|
-> Enable dom | Global enable |
-> ResetStrategy r | Whether to clear BRAM on asserted reset ( |
-> SNat n | Number of elements in BRAM |
-> a | Initial content of the BRAM (replicated n times) |
-> Signal dom addr | Read address |
-> Signal dom (Maybe (addr, a)) | (write address |
-> Signal dom a | Value of the |
Version of blockram that is initialized with the same value on all memory positions.
data ResetStrategy (r :: Bool) where Source #
BlockRAM primitives initialized with a data file
:: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> SNat n | Size of the blockRAM |
-> FilePath | File describing the initial content of the blockRAM |
-> Signal dom addr | Read address |
-> Signal dom (Maybe (addr, BitVector m)) | (write address |
-> Signal dom (BitVector m) | Value of the |
Create a blockRAM with space for n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Explicit.BlockRam for more information on how to use a Block RAM.
- Use the adapter
readNew
for obtaining write-before-read semantics like this:
.readNew
clk rst en (blockRamFile
clk en size file) rd wrM - See Clash.Explicit.BlockRam.File for more information on how to instantiate a Block RAM with the contents of a data file.
- See Clash.Sized.Fixed for ideas on how to create your own data files.
:: forall dom n m. (KnownDomain dom, KnownNat m, KnownNat n, HasCallStack) | |
=> Clock dom |
|
-> Enable dom | Global enable |
-> FilePath | File describing the initial content of the blockRAM |
-> Signal dom (Unsigned n) | Read address |
-> Signal dom (Maybe (Unsigned n, BitVector m)) | (write address |
-> Signal dom (BitVector m) | Value of the |
Create a blockRAM with space for 2^n
elements
- NB: Read value is delayed by 1 cycle
- NB: Initial output value is
undefined
NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:
| VHDL | Verilog | SystemVerilog | ===============+==========+==========+===============+ Altera/Quartus | Broken | Works | Works | Xilinx/ISE | Works | Works | Works | ASIC | Untested | Untested | Untested | ===============+==========+==========+===============+
Additional helpful information:
- See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
- Use the adapter
readNew
for obtaining write-before-read semantics like this:
.readNew
clk rst en (blockRamFilePow2' clk en file) rd wrM - See Clash.Explicit.BlockRam.File for more information on how to instantiate a Block RAM with the contents of a data file.
- See Clash.Explicit.Fixed for ideas on how to create your own data files.
BlockRAM read/write conflict resolution
:: (KnownDomain dom, NFDataX a, Eq addr) | |
=> Clock dom | |
-> Reset dom | |
-> Enable dom | |
-> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) | The |
-> Signal dom addr | Read address |
-> Signal dom (Maybe (addr, a)) | (Write address |
-> Signal dom a | Value of the |
Create read-after-write blockRAM from a read-before-write one
Utility functions
:: (KnownNat n, KnownDomain dom, NFDataX a, Default a) | |
=> Clock dom | Clock to the incoming signal is synchronized |
-> Reset dom | |
-> Enable dom | |
-> Signal dom a | Signal to create a window over |
-> Vec (n + 1) (Signal dom a) | Window of at least size 1 |
Give a window over a Signal
@ window4
:: (KnownNat n, NFDataX a, Default a, KnownDomain dom) | |
=> Clock dom | Clock to which the incoming signal is synchronized |
-> Reset dom | |
-> Enable dom | |
-> Signal dom a | Signal to create a window over |
-> Vec (n + 1) (Signal dom a) | Window of at least size 1 |
Give a delayed window over a Signal
windowD3 :: KnownDomain dom -> Clock dom -> Enable dom -> Reset dom ->Signal
dom Int ->Vec
3 (Signal
dom Int) windowD3 =windowD
>>>
simulateB (windowD3 systemClockGen resetGen enableGen) [1::Int,1,2,3,4] :: [Vec 3 Int]
[<0,0,0>,<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>... ...
riseEvery :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> SNat n -> Signal dom Bool Source #
oscillate :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Bool -> SNat n -> Signal dom Bool Source #
Oscillate a
for a given number of cycles, given the starting state.Bool
Testbench functions
:: (KnownDomain dom, Eq a, ShowX a) | |
=> Clock dom | |
-> Reset dom | |
-> String | Additional message |
-> Signal dom a | Checked value |
-> Signal dom a | Expected value |
-> Signal dom b | Return value |
-> Signal dom b |
Compares the first two Signal
s for equality and logs a warning when they
are not equal. The second Signal
is considered the expected value. This
function simply returns the third Signal
unaltered as its result. This
function is used by outputVerifier
.
NB: This function can be used in synthesizable designs.
:: forall l dom a. (KnownNat l, KnownDomain dom) | |
=> Clock dom | Clock to which to synchronize the output signal |
-> Reset dom | |
-> Vec l a | Samples to generate |
-> Signal dom a | Signal of given samples |
Example:
testInput :: KnownDomain dom => Clock dom -> Reset dom ->Signal
dom Int testInput clk rst =stimuliGenerator
clk rst $(listToVecTH
[(1::Int),3..21])
>>>
sampleN 14 (testInput systemClockGen resetGen)
[1,1,3,5,7,9,11,13,15,17,19,21,21,21]
:: forall l a dom. (KnownNat l, KnownDomain dom, DomainResetKind dom ~ 'Asynchronous, Eq a, ShowX a) | |
=> Clock dom | Clock to which the testbench is synchronized to |
-> Reset dom | Reset line of testbench |
-> Vec l a | Samples to compare with |
-> Signal dom a | Signal to verify |
-> Signal dom Bool | Indicator that all samples are verified |
Same as outputVerifier
but used in cases where the testbench domain and
the domain of the circuit under test are the same.
Tracing
Simple
:: (BitPack a, NFDataX a, Typeable a) | |
=> String | Name of signal in the VCD output |
-> Signal dom a | Signal to trace |
-> Signal dom a |
Trace a single signal. Will emit an error if a signal with the same name was previously registered.
NB associates the traced signal with a clock period of 1, which
results in incorrect VCD files when working with circuits that have
multiple clocks. Use traceSignal
when working with circuits that have
multiple clocks.
:: (KnownNat n, BitPack a, NFDataX a, Typeable a) | |
=> String | Name of signal in debugging output. Will be appended by _0, _1, ..., _n. |
-> Signal dom (Vec (n + 1) a) | Signal to trace |
-> Signal dom (Vec (n + 1) a) |
Trace a single vector signal: each element in the vector will show up as a different trace. If the trace name already exists, this function will emit an error.
NB associates the traced signal with a clock period of 1, which
results in incorrect VCD files when working with circuits that have
multiple clocks. Use traceSignal
when working with circuits that have
multiple clocks.
Tracing in a multi-clock environment
:: forall dom a. (KnownDomain dom, BitPack a, NFDataX a, Typeable a) | |
=> String | Name of signal in the VCD output |
-> Signal dom a | Signal to trace |
-> Signal dom a |
Trace a single signal. Will emit an error if a signal with the same name was previously registered.
NB Works correctly when creating VCD files from traced signal in
multi-clock circuits. However traceSignal1
might be more convenient to
use when the domain of your circuit is polymorphic.
:: forall dom a n. (KnownDomain dom, KnownNat n, BitPack a, NFDataX a, Typeable a) | |
=> String | Name of signal in debugging output. Will be appended by _0, _1, ..., _n. |
-> Signal dom (Vec (n + 1) a) | Signal to trace |
-> Signal dom (Vec (n + 1) a) |
Trace a single vector signal: each element in the vector will show up as a different trace. If the trace name already exists, this function will emit an error.
NB Works correctly when creating VCD files from traced signal in
multi-clock circuits. However traceSignal1
might be more convinient to
use when the domain of your circuit is polymorphic.
VCD dump functions
:: NFDataX a | |
=> (Int, Int) | (offset, number of samples) |
-> Signal dom a | (One of) the outputs of the circuit containing the traces |
-> [String] | The names of the traces you definitely want to be dumped in the VCD file |
-> IO (Either String Text) |
Produce a four-state VCD (Value Change Dump) according to IEEE 1364-{1995,2001}. This function fails if a trace name contains either non-printable or non-VCD characters.
Due to lazy evaluation, the created VCD files might not contain all the traces you were expecting. You therefore have to provide a list of names you definately want to be dumped in the VCD file.
For example:
vcd <- dumpVCD (0, 100) cntrOut ["main", "sub"]
Evaluates cntrOut long enough in order for to guarantee that the main
,
and sub
traces end up in the generated VCD file.
Exported modules
Synchronous signals
module Clash.Explicit.Signal
DataFlow interface
module Clash.Prelude.DataFlow
Datatypes
Bit vectors
module Clash.Sized.BitVector
module Clash.Prelude.BitIndex
module Clash.Prelude.BitReduction
Arbitrary-width numbers
module Clash.Sized.Signed
module Clash.Sized.Unsigned
module Clash.Sized.Index
Fixed point numbers
module Clash.Sized.Fixed
Fixed size vectors
module Clash.Sized.Vector
Perfect depth trees
module Clash.Sized.RTree
Annotations
module Clash.Annotations.TopEntity
Generics type-classes
Representable types of kind *
.
This class is derivable in GHC with the DeriveGeneric
flag on.
A Generic
instance must satisfy the following laws:
from
.to
≡id
to
.from
≡id
Instances
class Generic1 (f :: k -> Type) #
Representable types of kind * -> *
(or kind k -> *
, when PolyKinds
is enabled).
This class is derivable in GHC with the DeriveGeneric
flag on.
A Generic1
instance must satisfy the following laws:
from1
.to1
≡id
to1
.from1
≡id
Instances
Generic1 (V1 :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (U1 :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (Proxy :: k -> Type) | Since: base-4.6.0.0 |
Generic1 (FromTextShow1 f :: k -> Type) | |
Defined in TextShow.FromStringTextShow type Rep1 (FromTextShow1 f) :: k -> Type # from1 :: forall (a :: k0). FromTextShow1 f a -> Rep1 (FromTextShow1 f) a # to1 :: forall (a :: k0). Rep1 (FromTextShow1 f) a -> FromTextShow1 f a # | |
Generic1 (FromStringShow1 f :: k -> Type) | |
Defined in TextShow.FromStringTextShow type Rep1 (FromStringShow1 f) :: k -> Type # from1 :: forall (a :: k0). FromStringShow1 f a -> Rep1 (FromStringShow1 f) a # to1 :: forall (a :: k0). Rep1 (FromStringShow1 f) a -> FromStringShow1 f a # | |
Generic1 (FromGeneric1 f :: k -> Type) | |
Defined in TextShow.Generic type Rep1 (FromGeneric1 f) :: k -> Type # from1 :: forall (a :: k0). FromGeneric1 f a -> Rep1 (FromGeneric1 f) a # to1 :: forall (a :: k0). Rep1 (FromGeneric1 f) a -> FromGeneric1 f a # | |
Generic1 (Alt f :: k -> Type) | Since: base-4.8.0.0 |
Generic1 (Ap f :: k -> Type) | Since: base-4.12.0.0 |
Generic1 (Const a :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec (Ptr ()) :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec Char :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec Double :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec Float :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec Int :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (URec Word :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (Rec1 f :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (Sum f g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (Product f g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (K1 i c :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (f :+: g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (f :*: g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (WrappedBifunctor p a :: k1 -> Type) | |
Defined in Data.Bifunctor.Wrapped type Rep1 (WrappedBifunctor p a) :: k -> Type # from1 :: forall (a0 :: k). WrappedBifunctor p a a0 -> Rep1 (WrappedBifunctor p a) a0 # to1 :: forall (a0 :: k). Rep1 (WrappedBifunctor p a) a0 -> WrappedBifunctor p a a0 # | |
Generic1 (Joker g a :: k1 -> Type) | |
Generic1 (Clown f a :: k1 -> Type) | |
Generic1 (FromTextShow2 f a :: k1 -> Type) | |
Defined in TextShow.FromStringTextShow type Rep1 (FromTextShow2 f a) :: k -> Type # from1 :: forall (a0 :: k). FromTextShow2 f a a0 -> Rep1 (FromTextShow2 f a) a0 # to1 :: forall (a0 :: k). Rep1 (FromTextShow2 f a) a0 -> FromTextShow2 f a a0 # | |
Generic1 (FromStringShow2 f a :: k1 -> Type) | |
Defined in TextShow.FromStringTextShow type Rep1 (FromStringShow2 f a) :: k -> Type # from1 :: forall (a0 :: k). FromStringShow2 f a a0 -> Rep1 (FromStringShow2 f a) a0 # to1 :: forall (a0 :: k). Rep1 (FromStringShow2 f a) a0 -> FromStringShow2 f a a0 # | |
Functor f => Generic1 (Compose f g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (M1 i c f :: k -> Type) | Since: base-4.9.0.0 |
Functor f => Generic1 (f :.: g :: k -> Type) | Since: base-4.9.0.0 |
Generic1 (Sum p q a :: k1 -> Type) | |
Generic1 (Product f g a :: k1 -> Type) | |
Functor f => Generic1 (Tannen f p a :: k2 -> Type) | |
Functor (p (f a)) => Generic1 (Biff p f g a :: k3 -> Type) | |
Generic1 [] | Since: base-4.6.0.0 |
Generic1 Maybe | Since: base-4.6.0.0 |
Generic1 Par1 | Since: base-4.9.0.0 |
Generic1 Complex | Since: base-4.9.0.0 |
Generic1 Min | Since: base-4.9.0.0 |
Generic1 Max | Since: base-4.9.0.0 |
Generic1 First | Since: base-4.9.0.0 |
Generic1 Last | Since: base-4.9.0.0 |
Generic1 WrappedMonoid | Since: base-4.9.0.0 |
Defined in Data.Semigroup type Rep1 WrappedMonoid :: k -> Type # from1 :: forall (a :: k). WrappedMonoid a -> Rep1 WrappedMonoid a # to1 :: forall (a :: k). Rep1 WrappedMonoid a -> WrappedMonoid a # | |
Generic1 Option | Since: base-4.9.0.0 |
Generic1 ZipList | Since: base-4.7.0.0 |
Generic1 Identity | Since: base-4.8.0.0 |
Generic1 First | Since: base-4.7.0.0 |
Generic1 Last | Since: base-4.7.0.0 |
Generic1 Dual | Since: base-4.7.0.0 |
Generic1 Sum | Since: base-4.7.0.0 |
Generic1 Product | Since: base-4.7.0.0 |
Generic1 Down | Since: base-4.12.0.0 |
Generic1 NonEmpty | Since: base-4.6.0.0 |
Generic1 Tree | Since: containers-0.5.8 |
Generic1 FingerTree | Since: containers-0.6.1 |
Defined in Data.Sequence.Internal type Rep1 FingerTree :: k -> Type # from1 :: forall (a :: k). FingerTree a -> Rep1 FingerTree a # to1 :: forall (a :: k). Rep1 FingerTree a -> FingerTree a # | |
Generic1 Digit | Since: containers-0.6.1 |
Generic1 Node | Since: containers-0.6.1 |
Generic1 Elem | Since: containers-0.6.1 |
Generic1 ViewL | Since: containers-0.5.8 |
Generic1 ViewR | Since: containers-0.5.8 |
Generic1 FromGeneric | |
Defined in TextShow.Generic type Rep1 FromGeneric :: k -> Type # from1 :: forall (a :: k). FromGeneric a -> Rep1 FromGeneric a # to1 :: forall (a :: k). Rep1 FromGeneric a -> FromGeneric a # | |
Generic1 FromStringShow | |
Defined in TextShow.FromStringTextShow type Rep1 FromStringShow :: k -> Type # from1 :: forall (a :: k). FromStringShow a -> Rep1 FromStringShow a # to1 :: forall (a :: k). Rep1 FromStringShow a -> FromStringShow a # | |
Generic1 FromTextShow | |
Defined in TextShow.FromStringTextShow type Rep1 FromTextShow :: k -> Type # from1 :: forall (a :: k). FromTextShow a -> Rep1 FromTextShow a # to1 :: forall (a :: k). Rep1 FromTextShow a -> FromTextShow a # | |
Generic1 (Either a :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 ((,) a :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 (Arg a :: Type -> Type) | Since: base-4.9.0.0 |
Generic1 (WrappedMonad m :: Type -> Type) | Since: base-4.7.0.0 |
Defined in Control.Applicative type Rep1 (WrappedMonad m) :: k -> Type # from1 :: forall (a :: k). WrappedMonad m a -> Rep1 (WrappedMonad m) a # to1 :: forall (a :: k). Rep1 (WrappedMonad m) a -> WrappedMonad m a # | |
Functor f => Generic1 (Cofree f :: Type -> Type) | |
Functor f => Generic1 (Free f :: Type -> Type) | |
Generic1 (ListF a :: Type -> Type) | |
Generic1 (NonEmptyF a :: Type -> Type) | |
Generic1 ((,,) a b :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 (WrappedArrow a b :: Type -> Type) | Since: base-4.7.0.0 |
Defined in Control.Applicative type Rep1 (WrappedArrow a b) :: k -> Type # from1 :: forall (a0 :: k). WrappedArrow a b a0 -> Rep1 (WrappedArrow a b) a0 # to1 :: forall (a0 :: k). Rep1 (WrappedArrow a b) a0 -> WrappedArrow a b a0 # | |
Generic1 (FreeF f a :: Type -> Type) | |
Generic1 (CofreeF f a :: Type -> Type) | |
Generic1 (Tagged s :: Type -> Type) | |
Generic1 ((,,,) a b c :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 ((,,,,) a b c d :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 ((,,,,,) a b c d e :: Type -> Type) | Since: base-4.6.0.0 |
Generic1 ((,,,,,,) a b c d e f :: Type -> Type) | Since: base-4.6.0.0 |
Type-level natural numbers
module GHC.TypeLits
module GHC.TypeLits.Extra
module Clash.Promoted.Nat
module Clash.Promoted.Nat.Literals
module Clash.Promoted.Nat.TH
Type-level strings
module Clash.Promoted.Symbol
Template Haskell
A Lift
instance can have any of its values turned into a Template
Haskell expression. This is needed when a value used within a Template
Haskell quotation is bound outside the Oxford brackets ([| ... |]
) but not
at the top level. As an example:
add1 :: Int -> Q Exp add1 x = [| x + 1 |]
Template Haskell has no way of knowing what value x
will take on at
splice-time, so it requires the type of x
to be an instance of Lift
.
A Lift
instance must satisfy $(lift x) ≡ x
for all x
, where $(...)
is a Template Haskell splice.
Lift
instances can be derived automatically by use of the -XDeriveLift
GHC language extension:
{-# LANGUAGE DeriveLift #-} module Foo where import Language.Haskell.TH.Syntax data Bar a = Bar1 a (Bar a) | Bar2 String deriving Lift
Nothing
Instances
Type classes
Clash
module Clash.Class.AutoReg
module Clash.Class.BitPack
module Clash.Class.Exp
module Clash.Class.Num
module Clash.Class.Resize
Other
module Control.Applicative
module Data.Bits
module Data.Default.Class
Exceptions
module Clash.XException
Named types
module Clash.NamedTypes
Magic
module Clash.Magic
Haskell Prelude
module Clash.HaskellPrelude