Wired: Low-level hardware design in Haskell Hardware Description - - PowerPoint PPT Presentation

wired low level hardware design in haskell
SMART_READER_LITE
LIVE PREVIEW

Wired: Low-level hardware design in Haskell Hardware Description - - PowerPoint PPT Presentation

Wired: Low-level hardware design in Haskell Hardware Description and Verification Emil Axelsson, May 2007 Goal (example) bitMult = row andBitM where andBitM = and2 *=* ((cro *||* wireT0) *||* wireX) Help to reach the goal Logic


slide-1
SLIDE 1

Wired: Low-level hardware design in Haskell

Hardware Description and Verification Emil Axelsson, May 2007

slide-2
SLIDE 2

Goal (example)

bitMult = row andBitM where andBitM = and2 *=* ((cro *||* wireT0) *||* wireX)

slide-3
SLIDE 3

Help to reach the goal

  • Logic programming library (LP) in Haskell
  • Relational Lava (uses LP)

exArith = do (res,x) <- free res <== x |-| 3 x <== 5 |*| 2 return res *Main> runLP exArith [7]

Setup constraints Solve constraints

slide-4
SLIDE 4

Lava

  • A Lava “circuit”:

A Haskell program that generates a netlist (directed graph with simple boolean gates as nodes)

  • Feels like functional programming

inv :: Signal Bool -> Signal Bool *Main> simulate (inv ->- inv) low low *Main> (not . not) False False

slide-5
SLIDE 5

Recursive generators

*Main> simulate (map (inv->-inv)) [low,high,low] [low,high,low]

Simple, compact descriptions for complicated structures

slide-6
SLIDE 6

Relational Lava (RLava)

  • Lava circuits have predefined signal-flow

direction

  • Reason: Circuits are functions
  • Ideally, connection patterns should abstract

away from signal flow (think about real electrical wires)

slide-7
SLIDE 7

Relational Lava (RLava)

  • RLava models circuits as relations instead:
  • Relations implemented using the LP library
  • RLava's combinator library mimics Lava's
  • Simulation, verification, synthesis, etc. is done

through Lava (using convert)

*Main> L.simulate (convert (inv <> inv)) L.low low

slide-8
SLIDE 8

Signal flow abstraction

exRLava = mapM ((inv <> wire 1)

  • |-

(converse inv <> wire 1) ) wire :: Term Int -> Signal -> LP Signal

slide-9
SLIDE 9

Wired background

  • Netlists are lacking geometrical information
  • Cell placement and wire routing needed before

fabrication

  • Pre-layout performance estimation very hard!!

– Main reason: hard to predict wire properties

  • Automatic tools are often not good enough

– Evidence: Large parts of Intel's chips are designed manually

  • Can Haskell make manual design easier?
slide-10
SLIDE 10

Basic idea

  • Use connection patterns as in Lava, but let

them also represent layout

  • Example, row:
  • This has been done before (e.g. in Lava), but

we want a more direct connection to standard cell layout, including wiring:

slide-11
SLIDE 11

Wired circuits

  • Wired circuit: A rectangular tile characterized by

its four ports (w, n, s and e)

w e n s

and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins

slide-12
SLIDE 12

Wired example

(*||*) :: ( Port wL, Port nL, Port sL, Port x , Port nR, Port sR, Port eR ) => Circ wL nL sL x -> Circ x nR sR eR

  • > Circ wL (nL,nR) (sL,sR) eR

and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins

wL eR (nL,nR) (sL,sR)

slide-13
SLIDE 13

Wired example

(*||*) :: ( Port wL, Port nL, Port sL, Port x , Port nR, Port sR, Port eR ) => Circ wL nL sL x -> Circ x nR sR eR

  • > Circ wL (nL,nR) (sL,sR) eR

and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins and2 *||* and2 :: Circ Ins (((Sig, Sig), Ins), ((Sig, Sig), Ins)) ((Ins, Sig), (Ins, Sig)) Ins renderCircuit "circ" (and2 *||* and2)

wL eR (nL,nR) (sL,sR)

slide-14
SLIDE 14

Wires

wireX :: Circ Sig Ins Ins Sig wireY :: Circ Ins Sig Sig Ins wireL0 :: Circ Ins Sig Ins Sig wireT0 :: Circ Sig Ins Sig Sig cro :: Circ Sig Sig Sig Sig

slide-15
SLIDE 15

Wires

wireX :: Circ Sig Ins Ins Sig wireY :: Circ Ins Sig Sig Ins wireL0 :: Circ Ins Sig Ins Sig wireT0 :: Circ Sig Ins Sig Sig cro :: Circ Sig Sig Sig Sig bitMult = row andBitM where andBitM = and2 *=* ((cro *||* wireT0) *||* wireX) renderCircuit "circ" (bitMult `ofLengthX` 3)

slide-16
SLIDE 16

Size inference

  • Haskell type system checks that interfaces of

connected circuits match, but not sizes

  • Sizes are checked using logical constraints in

the LP library

  • By solving size constraints we also get size

inference for free!

slide-17
SLIDE 17

Size inference

bitMult `ofLengthX` 3 64 x

*=*

length 3 Unifies intermediate ports

slide-18
SLIDE 18

Combinators

(*=*) :: ( Port wL, Port x, Port sL, Port eL , Port wH, Port nH, Port eH ) => Circ wL x sL eL -> Circ wH nH x eH

  • > Circ (wL,wH) nH sL (eL,eH)

(*||~) :: (Port w, Port n, Port s, Port e, Port x) => Circ w n s x

  • > Circ x [n] [s] e
  • > Circ w [n] [s] e

(*=~) :: (Port w, Port n, Port s, Port e, Port x) => Circ w x s e

  • > Circ [w] n x [e]
  • > Circ [w] n s [e]
slide-19
SLIDE 19

Patterns

rowN :: (Port x, Port n, Port s) => Term Int -> Circ x n s x -> Circ x [n] [s] x rowN n circ = unintR n rowN' where rowN' 0 = nilY rowN' n = circ *||~ rowN' (n-1) row :: (Port y, Port n, Port s) => Circ y n s y -> Circ y [n] [s] y row circ = do cR <- free l <- lengthR $ north cR l <== (lengthR $ south cR) cR <== rowN l circ n

nilY

circ

slide-20
SLIDE 20

Softening

bitMultR :: (RLava.Signal, [RLava.Signal]) -> LP [RLava.Signal] bitMultR (x,as) = do ys <- sequence [free | _ <- as] -- Outputs (w,n,s,e) <- soften (bitMult `ofLengthX` term (length as)) w =:= ((),x) n =:= term [((a,()), ()) | a <- as] s =:= term [((),y) | y <- ys] return ys *Main> L.simulate (convert bitMultR) (L.high, [L.low, L.high]) [low,high]

slide-21
SLIDE 21

Output

  • Simulation, verification, synthesis:

Wired → RLava → Lava

  • Timing estimation:

Wired → RLava

  • Visualization:

Wired → Postscript

  • Real layout (not yet):

Wired → ?? → GDS2

slide-22
SLIDE 22

Case study: Prefix circuits

Given inputs x1, x2, … xn compute y1 = x1 y2 = x1 ○ x2 … yn = x1 ○ x2 ○ … ○ xn for ○, an associative (but not necessarily commutative) operator

slide-23
SLIDE 23

Prefix circuits (2)

  • Very central component in microprocessors
  • Most common use: Computing carries in fast

adders

  • Trying different operators

– Addition:

prefix (+) [1,2,3,4]

slide-24
SLIDE 24

Prefix circuits (2)

  • Very central component in microprocessors
  • Most common use: Computing carries in fast

adders

  • Trying different operators

– Addition:

prefix (+) [1,2,3,4] = [1, 1+2, 1+2+3, 1+2+3+4] = [1,3,6,10]

slide-25
SLIDE 25

Prefix circuits (2)

  • Very central component in microprocessors
  • Most common use: Computing carries in fast

adders

  • Trying different operators

– Addition:

prefix (+) [1,2,3,4] = [1, 1+2, 1+2+3, 1+2+3+4] = [1,3,6,10]

– Boolean OR:

prefix (||) [F,F,F,T,F,T,T,F]

slide-26
SLIDE 26

Prefix circuits (2)

  • Very central component in microprocessors
  • Most common use: Computing carries in fast

adders

  • Trying different operators

– Addition:

prefix (+) [1,2,3,4] = [1, 1+2, 1+2+3, 1+2+3+4] = [1,3,6,10]

– Boolean OR:

prefix (||) [F,F,F,T,F,T,T,F] = [F,F,F,T,T,T,T,T]

slide-27
SLIDE 27

Prefix circuits (3)

Implementation choices (relying on associativity): prefix (○) [x1,x2,x3,x4] = [y1,y2,y3,y4]

– Serial:

y4 = ((x1○x2) ○ x3) ○ x4

– Parallel:

y4 = (x1○x2) ○ (x3○x4)

– Sharing:

y4 = y3 ○ x4

slide-28
SLIDE 28

Serial prefix (standard diagram)

  • perator

8 inputs depth 7 size 7

1 2

… 7 8

1 1:2

… 1:7 1:8

slide-29
SLIDE 29

Parallel prefix (Sklansky)

  • Serial: Fewer operators, linear logical depth
  • Parallel: More operators, logarithmic depth
slide-30
SLIDE 30

Sklansky in Lava

sklansky op [a] = [a] sklansky op as = ls' ++ [op (last ls', r) | r <- rs'] where k = (length as + 1) `div` 2 (ls,rs) = splitAt k as ls' = sklansky op ls rs' = sklansky op rs

slide-31
SLIDE 31

Sklansky in Lava

sklansky op [a] = [a] sklansky op as = ls' ++ [op (last ls', r) | r <- rs'] where k = (length as + 1) `div` 2 (ls,rs) = splitAt k as ls' = sklansky op ls rs' = sklansky op rs

slide-32
SLIDE 32

Abstract wires

  • Need a notion of abstract wires in Wired
  • These are called buses

sklansky :: ((a,a) -> a) -> [a] -> [a]

Can contain lots of concrete wires

slide-33
SLIDE 33

Buses

  • Generalization of wireX, wireY, wireLX,

wireTX, cro

  • Shape determined by context

wireT0 busT0 Example instance

slide-34
SLIDE 34

Bus example

bus :: Circ (Sig, Ins, (Sig,Sig)) Ins (Sig, Ins, (Sig,Sig)) (Sig, Ins, (Sig,Sig)) bus = busT0 `withConstraint` \cct -> do [a,b,c,d,e,f] <- replicateM 6 free west cct === tup3 (sig1 a) (Ins 60) (sig2 b c) south cct === tup3 (sig1 d) (Ins 90) (sig2 e f)

slide-35
SLIDE 35

Sklansky in Wired

sklansky 0 op opFO = rowN 1 $ nilX `withConstraint` \circ -> north circ <== (structure =<< asLP south =<< op) sklansky d op opFO = (joinL ~||~ joinR) *=~ (skl~||~skl) where skl = sklansky (d-1) op opFO n = term (2^(d-1) - 1)

  • p' = op *=* alignLeft 4
  • pFO' = opFO *=* alignLeft 4

joinL = rowN n (busY*=*busY) ~||* (busT1*=*busY) joinR = rowN n opFO' ~||* op'

slide-36
SLIDE 36

Sklansky with single-bit operator

renderCircuit "circ" $ sklansky 3 dot1 dot1FO

slide-37
SLIDE 37

Sklansky with pair operator

renderCircuit "circ" $ sklansky 3 dot dotFO

slide-38
SLIDE 38

Summary

  • Haskell can alleviate manual design
  • Being built on top of other libraries, Wired itself

is quite a small library

  • LP is the perfect foundation for RLava/Wired
  • Read about LP and Wired:

Matthew Naylor, Emil Axelsson and Colin Runciman.

A Functional-Logic Library for Wired. HFL'07

http://www.cs.chalmers.se/~emax/wired/documents/LP_HFL07.pdf

slide-39
SLIDE 39

Future work

  • Clever generators
  • Connection to realistic design flow
  • More performance analyses

– Power, cross-talk, etc.