topEntity
Domain
: synthesis domain
System
: Useful for simulationclash --vhdl MAC.hs
Signal
values represent synchronous values. ie, values that change with respect to a clock.
HiddenClockResetEnable
.
exposeClockResetEnable
.NFDataX
To be synthesizable, data type needs to be an instance of NFDataX
, a typeclass defined in clash-prelude.
It's like NFData
. NFData
says that the type has a normal form (ie, is fully evaluatable and doesn't diverge). (I guess NF stands for 'normal form').
This makes the evaluation eager?
NFDataX
is NFData
with support for undefined values.
(cf: from here)
+---------------+
Input --->-| |------> Output
| Combinational |
| logic |
+---| |---+
| +---------------+ |
Current ^ V Next
state | +---------------+ | state
| | | |
+-<-| Memory |-<-+
| elements |
+---------------+
–
-- | Function to run a mealy machine
= [] -- no input means no output
run _ _ [] :inputs) = output: outputs
run func state (inputwhere
= func input state
(output, state′) = run func state′ inputs
outputs
-- | Transition function for a mealy machine
func :: InputSignals → State a → (OutputSignals, State a)
= (output, state′)
func input state where
...
...
–
Type:
mealy
:: (KnownDomain dom,
GHC.Classes.IP (Clash.Signal.HiddenClockName dom) (Clock dom),
GHC.Classes.IP (Clash.Signal.HiddenEnableName dom) (Enable dom),
GHC.Classes.IP (Clash.Signal.HiddenResetName dom) (Reset dom),
NFDataX s) =>
(s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
Transition function of the mealy machine:
(s -- ^ current state
-> i -- ^ next input
-> (s, o)) -- ^ next state, next output (produced /during/ the transition)
s -- ^ initial state of mealy machine
-> Signal dom i -- ^ input signal
-> Signal dom o -- ^ output signal
From base
itself:
From clash-prelude
:
à la ports in VHDL, I guess.
Use :::
. An example: https://github.com/clash-lang/clash-compiler/pull/2584/files
Using an annotation
Example:
{-# ANN topEntity
(Synthesize
{ t_name = "topEntity"
, t_inputs = [ PortName "clk"
, PortName "rst"
, PortName "en"
, PortName "inp" ]
, t_output = PortName "res"
}) #-}
testBench
testBench
has to be in root modulehttps://hackage.haskell.org/package/clash-prelude-1.8.1/docs/Clash-Tutorial.html
outputVerifier
True
when all test cases have been testedFalse
Signal
type.register
register
:: (HiddenClockResetEnable dom, NFDataX a)
=> a -> Signal dom a -> Signal dom a
Clash.Prelude> sampleN @System 5 $ register 8 $ fromList [1,2,3,4]
[8,8,2,3,4]
Conversion between Bitvector and Int:
Clash.Prelude> pack (59 :: Unsigned 8)
0b0011_1011
Clash.Prelude> :t pack (59 :: Unsigned 8)
pack (59 :: Unsigned 8) :: BitVector 8
Clash.Prelude> :t pack (59 :: Unsigned 9)
pack (59 :: Unsigned 9) :: BitVector 9
Clash.Prelude> unpack 0b101 ::Signed 3
-3
Clash.Prelude> unpack 0b101 ::Unsigned 3
5
—
Some operations:
-- Bitwise OR
Clash.Prelude Prelude> (Clash.Prelude..|.) 0b1001 0b1010
11
—
bLit:
Clash.Prelude> import qualified Data.List as List
Clash.Prelude List> $(bLit (List.replicate 4 '0'))
0b1111
a | b | c | d | g | e | f | g | |
---|---|---|---|---|---|---|---|---|
0 | T | T | T | T | T | T | T | |
1 | T | T | ||||||
2 | T | T | T | T | T | |||
3 | T | T | T | T |
import Data.Char
import qualified Data.Map
a :: [(Char, Vec 7 Bool)]
-- a b c d e f g
= [('0', True :> True :> True :> True :> True :> True :> True :> Nil),
a '1', False :> True :> True :> False :> False :> False :> False :> Nil),
('?', True :> True :> False :> False :> True :> False :> True :> Nil)]
(= Data.Map.fromList a b
Signal
manuallyNot synthesizable. Shouldn't be used in production code!!
> import Clash.Signal.Internal
λ> :t (1 :- 2)
λ1 :- 2) :: Num a => Signal dom a
(
> 1 :: Signal System Int
λ1 1 1 1 1 ...............
CLASH_OPAQUE
: From ghc itself