Upload
mjgajda
View
639
Download
6
Embed Size (px)
Citation preview
Haskell.SG MeetUp
CλaSH: way to compile hardware with Haskell
Presented byMichał J. Gajda
April 22nd of 2015
How to get a logical circuit
NANDgate
NORgate
XORgate
NOTgate
Thanks for images of Chuck Moore: http://www.colorforth.com
Gates
http://hyperphysics.phy-astr.gsu.edu/hbase/electronic
HDL: VHDL
FPGA workflow with Xilinx
Basic concepts
● Logical functions:
– And, or, not, xor, nand...
– multiply, add, divide...
– <function> :: Bit -> ... -> Bit
– type Bit = BitVector 1● Clocks
● Registers – hold data until next rising edge of clock
– register :: a -> Signal a -> Signal a
Basic concepts
● Time for charges to go through the gates...need to be shorter than the clock cycle:
– delay = 1/frequency● Three state logic:
– '1' True (+, source charge)
– '0' False (ground, sink charge)
– 'Z' High impedance (disconnected)
Level up: netlist
Level up: netlist with state
CλaSH – GHC plugin
Key types
● Lifting constant:
Signal a is instance of:
– Applicative– Foldable (non synth.) ~ Bundle (synth.)
● signal :: a -> Signal a● signal' :: a -> Signal' clk a● clk – clock as type paramete
Connectors
● mealy :: ((state, input) ->
(state, output)) ->
state ->
Signal input -> Signal output● class Bundle a where
– type Unbundled a– bundle :: Unbundled a -> Signal a– unbundle :: Signal a -> Unbundled a
Clock domains
● All previous are actually type aliases:
– type Signal a = Signal' SystemClock a– register = register' systemClock– counter' :: (Num s, Eq s) => s -> Signal
Bool
counter' limit = (fsm `mealy` 0) $ signal ()
where
fsm st () | limit == st = (0, True)
| otherwise = (st+1, False)
Example of bundle
data SevenSegmentDisplay n = SevenSegmentDisplay {
anodeIndex :: Unsigned n
-- ^ Anode index
, currentDigit :: SevenSegDigit
-- ^ Seven segment signal for th current anode
}
deriving (Show)
Instance of Bundle
instance (KnownNat n) =>
Bundle (SevenSegmentDisplay n) where
type Unbundled' t (SevenSegmentDisplay n) =
(Signal' t (Unsigned n), Signal' t SevenSegDigit)
unbundle' _ s = (anodeIndex <$> s,
currentDigit <$> s)
bundle' _ (anode, digit) =
SevenSegmentDisplay <$> anode <*> digit
Use of bundle
HourClock :: (KnownNat n) => Vec n (BCDDigit)
hourClock = bundle (secondsCounter
:> tenSecondsCounter
:> minutesCounter
:> tenMinutesCounter
:> Nil )
secondsCounter :: Signal BCDDigit
Clash workflowHaskell code
Validation
Standard HDL toolchain
Logical functions:a > b
Clocked mealy machines:Signal a > Signal b
Sample states of the machines:sampleN CLaSH compiler plugin
CLaSH prelude
Functional simulation
Simulated environment:inputs
UI
VHDL codeVerilog code
HDL compilation
Routing compiled components
FPGA bitcode
Upload of bitcode
FPGA device configuration
Display
sevenSegmentDisplay digits =
bundle (digitAnode <$> whichDigit ,
sevenSegmentDigit <$> currentDigit)
where
(whichDigit, _)= counter
(myMaxIndex $ unbundle digits)
hz1000
currentDigit = (!!) <$> digits <*> whichDigit
myMaxIndex = fromIntegral . (+1) . maxIndex
Interfacing FPGA
● TopEntity.vhdl– Wrapper
– translating pin names
– translating types to STD_LOGIC pins
● See my code and Xilinx ISE project on GitHub:
https://github.com/mgajda/clashdemodigitalclock
What we get?
● Concise description● Fast behavioural testing in GHC● VHDL code to be processed by synthesis tool
● No timing analysis until VHDL synthesis● No use of custom netlists
Not necessarily less efficient than VHDL
This is from ClaSH paper.