21
Haskell.SG MeetUp CλaSH: way to compile hardware with Haskell Presented by Michał J. Gajda April 22 nd of 2015

On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

  • Upload
    mjgajda

  • View
    639

  • Download
    6

Embed Size (px)

Citation preview

Page 1: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Haskell.SG MeetUp

CλaSH: way to compile hardware with Haskell

Presented byMichał J. Gajda

April 22nd of 2015

Page 2: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

How to get a logical circuit

NANDgate

NORgate

XORgate

NOTgate

Thanks for images of Chuck Moore: http://www.colorforth.com

Page 3: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Gates

http://hyperphysics.phy-astr.gsu.edu/hbase/electronic

Page 4: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

HDL: VHDL

Page 5: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

FPGA workflow with Xilinx

Page 6: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 7: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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)

Page 8: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Level up: netlist

Page 9: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Level up: netlist with state

Page 10: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

CλaSH – GHC plugin

Page 11: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 12: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 13: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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)

Page 14: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Example of bundle

data SevenSegmentDisplay n = SevenSegmentDisplay {

anodeIndex :: Unsigned n

-- ^ Anode index

, currentDigit :: SevenSegDigit

-- ^ Seven segment signal for th current anode

}

deriving (Show)

Page 15: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 16: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Use of bundle

HourClock :: (KnownNat n) => Vec n (BCDDigit)

hourClock = bundle (secondsCounter

:> tenSecondsCounter

:> minutesCounter

:> tenMinutesCounter

:> Nil )

secondsCounter :: Signal BCDDigit

Page 17: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 18: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Display

sevenSegmentDisplay digits =

bundle (digitAnode <$> whichDigit ,

sevenSegmentDigit <$> currentDigit)

where

(whichDigit, _)= counter

(myMaxIndex $ unbundle digits)

hz1000

currentDigit = (!!) <$> digits <*> whichDigit

myMaxIndex = fromIntegral . (+1) . maxIndex

Page 19: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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/clash­demo­digitalclock

Page 20: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

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

Page 21: On using Haskell DSL - CLaSH, to implement a simple digital stopwatch on FPGA

Not necessarily less efficient than VHDL

This is from ClaSH paper.