wired low level hardware design in haskell

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


  1. Wired: Low-level hardware design in Haskell Hardware Description and Verification Emil Axelsson, May 2007

  2. Goal (example) bitMult = row andBitM where andBitM = and2 *=* ((cro *||* wireT0) *||* wireX)

  3. Help to reach the goal ● Logic programming library (LP) in Haskell exArith = do *Main> runLP exArith (res,x) <- free [7] res <== x |-| 3 x <== 5 |*| 2 Solve return res constraints Setup constraints ● Relational Lava (uses LP)

  4. Lava ● A Lava “circuit”: A Haskell program that generates a netlist (directed graph with simple boolean gates as nodes) inv :: Signal Bool -> Signal Bool *Main> simulate (inv ->- inv) low low ● Feels like functional programming *Main> (not . not) False False

  5. Recursive generators *Main> simulate (map (inv->-inv)) [low,high,low] [low,high,low] Simple, compact descriptions for complicated structures

  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)

  7. Relational Lava (RLava) ● RLava models circuits as relations instead: *Main> L.simulate (convert (inv <> inv)) L.low low ● Relations implemented using the LP library ● RLava's combinator library mimics Lava's ● Simulation, verification, synthesis, etc. is done through Lava (using convert )

  8. Signal flow abstraction wire :: Term Int -> Signal -> LP Signal exRLava = mapM ((inv <> wire 1) -|- (converse inv <> wire 1) )

  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?

  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 :

  11. Wired circuits ● Wired circuit: A rectangular tile characterized by its four ports ( w , n , s and e ) n w e s and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins

  12. Wired example and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins (*||*) :: ( Port wL, Port nL, Port sL, Port x , Port nR, Port sR, Port eR ) (nL,nR) => Circ wL nL sL x -> Circ x nR sR eR -> Circ wL (nL,nR) (sL,sR) eR wL eR (sL,sR)

  13. Wired example and2 :: Circ Ins ((Sig, Sig), Ins) (Ins, Sig) Ins (*||*) :: ( Port wL, Port nL, Port sL, Port x , Port nR, Port sR, Port eR ) (nL,nR) => Circ wL nL sL x -> Circ x nR sR eR -> Circ wL (nL,nR) (sL,sR) eR wL eR and2 *||* and2 (sL,sR) :: Circ Ins (((Sig, Sig), Ins), ((Sig, Sig), Ins)) ((Ins, Sig), (Ins, Sig)) Ins renderCircuit "circ" (and2 *||* and2)

  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

  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)

  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!

  17. Size inference bitMult `ofLengthX` 3 length 3 x 64 *=* Unifies intermediate ports

  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]

  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 nilY circ rowN' 0 = nilY rowN' n = circ *||~ rowN' (n-1) n 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

  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]

  21. Output ● Simulation, verification, synthesis: Wired → RLava → Lava ● Timing estimation: Wired → RLava ● Visualization: Wired → Postscript ● Real layout (not yet): Wired → ?? → GDS2

  22. Case study: Prefix circuits Given inputs x 1 , x 2 , … x n compute y 1 = x 1 y 2 = x 1 ○ x 2 … y n = x 1 ○ x 2 ○ … ○ x n for ○, an associative (but not necessarily commutative) operator

  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]

  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]

  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] prefix (||) [F,F,F, T ,F, T , T ,F] – Boolean OR:

  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] prefix (||) [F,F,F, T ,F, T , T ,F] – Boolean OR: = [F,F,F, T , T , T , T , T ]

  27. Prefix circuits (3) Implementation choices (relying on associativity): prefix (○) [ x 1 , x 2 , x 3 , x 4 ] = [ y 1 , y 2 , y 3 , y 4 ] – Serial: y 4 = (( x 1 ○ x 2 ) ○ x 3 ) ○ x 4 – Parallel: y 4 = ( x 1 ○ x 2 ) ○ ( x 3 ○ x 4 ) – Sharing: y 4 = y 3 ○ x 4

  28. Serial prefix (standard diagram) 1 2 … 7 8 operator 8 inputs depth 7 size 7 1 1:2 … 1:7 1:8

  29. Parallel prefix (Sklansky) ● Serial: Fewer operators, linear logical depth ● Parallel: More operators, logarithmic depth

  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

  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

  32. Abstract wires sklansky :: ((a,a) -> a) -> [a] -> [a] Can contain lots of concrete wires ● Need a notion of abstract wires in Wired ● These are called buses

  33. Buses ● Generalization of wireX , wireY , wireLX , wireTX , cro ● Shape determined by context Example instance busT0 wireT0

  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)

  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) op' = op *=* alignLeft 4 opFO' = opFO *=* alignLeft 4 joinL = rowN n (busY*=*busY) ~||* (busT1*=*busY) joinR = rowN n opFO' ~||* op'

  36. Sklansky with single-bit operator renderCircuit "circ" $ sklansky 3 dot1 dot1FO

  37. Sklansky with pair operator renderCircuit "circ" $ sklansky 3 dot dotFO

  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

  39. Future work ● Clever generators ● Connection to realistic design flow ● More performance analyses – Power, cross-talk, etc.

Recommend


More recommend