Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

CLaSH HIW 2014

475 views

Published on

HIW 2014 talk on CLaSH (http://christiaanb.github.io/clash2)

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

CLaSH HIW 2014

  1. 1. CλaSH Compiling Circuit Descrip5ons
  2. 2. Overview • What is CλaSH? • The CλaSH compiler pipeline • Transforma5ons • Structural vs Behavioural • CλaSH vs Embedded • Demo • Conclusions Slide 2 of 35
  3. 3. Hardware Design math Matlab/C Schema5c Slide 3 of 35
  4. 4. Hard work, LINT tools, test benches, staring at two 30” screens full of waveforms, some asser5ons (SVA) and linear logic (PSL), and a liSle magic. Slide 4 of 35
  5. 5. “Correct” VHDL Slide 5 of 35
  6. 6. Synthesis Slide 6 of 35
  7. 7. They’re about the same Slide 7 of 35
  8. 8. What is CλaSH? Slide 8 of 35
  9. 9. What is CλaSH? • CAES Language for Synchronous Hardware • A compiler that views Haskell programs as structural circuit descrip5ons. • Input: (seman5c) subset of Haskell • Output: Low-­‐level synthesisable VHDL Slide 9 of 35
  10. 10. Small CλaSH example mac :: Signal (Signed 6) -> Signal (Signed 6) -> Signal (Signed 6) mac x y = acc where acc = register 0 ((x * y) + acc) Slide 10 of 35
  11. 11. Another example dotp :: Vec 4 (Signed 10) -> Vec 4 (Signed 10) -> Signed 10 dotp xs ys = foldl (+) 0 $ zipWith (*) xs ys Slide 11 of 35
  12. 12. Compiler Pipeline • Use GHC API to convert Haskell to GHC’s Core – Custom set of op5miza5ons enabled – No CorePrep (Breaks up Integer literals) • Transform to CλaSH’s Core (no coercions) • Normalize CλaSH Core • Convert to Netlist datatype – Includes primi5ve handling • “PreSy” print VHDL Slide 12 of 35
  13. 13. Core: System F’ish + letrec + case data Term = Var Type TmName -- ^ Variable reference | Data DataCon -- ^ Datatype constructor | Literal Literal -- ^ Literal | Prim Text Type -- ^ Primitive | Lam (Bind Id Term) -- ^ Term-abstraction | TyLam (Bind TyVar Term) -- ^ Type-abstraction | App Term Term -- ^ Application | TyApp Term Type -- ^ Type-application | Letrec (Bind (Rec [LetBinding]) Term) -- ^ Recursive let-binding | Case Term Type [Bind Pat Term] -- ^ Case-expression data Type = VarTy Kind TyName -- ^ Type variable | ConstTy ConstTy -- ^ Type constant | ForAllTy (Bind TyVar Type) -- ^ Polymorphic Type | AppTy Type Type -- ^ Type Application | LitTy LitTy -- ^ Type literal Slide 13 of 35
  14. 14. Structure: an “opera5onal” seman5cs Syntac'cal element • Func5on applica5on • Example: f(g x) Structure • Component instan5a5on • Example: x g f Slide 14 of 35
  15. 15. Structure: an “opera5onal” seman5cs Syntac'cal element • Lamda-­‐binder • Example: x y. x Structure • Input port • Example: x y Slide 15 of 35
  16. 16. Structure: an “opera5onal” seman5cs Syntac'cal element • Case-­‐statement on a product type, or, projec5on • Example: case z of (a,b) -> a Structure • Con5nue with one of the wires, basically a NOP • Example: a b Slide 16 of 35
  17. 17. Structure: an “opera5onal” seman5cs Syntac'c element • Case-­‐statement on a sum-­‐ type. • Example: case z of True -> a False -> b Structure • Mul5plexer of the alterna5ves, with the subject driving the selec5on • Example: z a b Slide 17 of 35
  18. 18. Normal form • Only lamba’s at outermost posi5on • Lambda’s followed by a single letrec • Let-­‐bound values all in ANF • Letrec body is a variable reference • Completely monomorphic and first-­‐order Slide 18 of 35
  19. 19. Compila5on example Haskell data Opc = Add | Mul alu Add = (+) alu Mul = (*) Core alu = ds -> case ds of Add -> (+) Mul -> (*) Slide 19 of 35
  20. 20. Compila5on example Core alu = ds -> case ds of Add -> (+) Mul -> (*) Normalised Core alu = ds x y -> let a = (+) x y b = (∗) x y r = case ds of Add -> a Mul -> b in res Slide 20 of 35
  21. 21. Transforma5ons • Preserve first-­‐order func5on hierarchy • Don’t lose sharing => larger circuit • Open ques5on: is case-­‐of-­‐case bad? case (case e of {p1 -> a1 .. pN -> aN}) {q1 -> b1 .. qN -> bN} => case e of {p1 -> case a1 of {q1 -> b1 .. qN -> bN} … pN -> case aN of {q1 -> b1 .. qN -> bN } • Currently: only when the subject is higher-­‐order Slide 21 of 35
  22. 22. Primi5ve templates [ { "BlackBox" : { "name" : "CLaSH.Signal.Internal.register#” , "templateD" : "register_~SYM[0] : block signal ~SYM[1] : ~TYP[2]; signal ~SYM[2] : ~TYP[1]; begin ~SYM[2] <= ~ARG[1]; process(~CLK[0],~RST[0],~SYM[2]) begin if ~RST[0] = '0' then ~SYM[1] <= ~SYM[2]; elsif rising_edge(~CLK[0]) then ~SYM[1] <= ~ARG[2]; end if; end process; ~RESULT <= ~SYM[1]; end block;" } } ] Slide 22 of 35
  23. 23. Embedded DSL / Lava • Why CλaSH when we already have Lava? • Building parallel circuits in Haskell for more than a decade • “Straighkorward” to implement: – Don’t have to deal with higher-­‐order func5ons or recursions Slide 23 of 35
  24. 24. PATTERN MATCHING! Slide 24 of 35
  25. 25. EDSL vs PaSern Matching • You can use paSern matching as part of a func5ons that generates a circuit. • But you cannot use paSern matching as way to specify the behaviour of the circuit. Slide 25 of 35
  26. 26. EDSL vs PaSern Matching Not observable f :: Bool -> Signal Int8 -> Signal Int8 f True a = a + 1 f False a = a - 1 Invalid pa:ern f :: Signal Bool -> Signal Int8 -> Signal Int8 f True a = a + 1 f False a = a - 1 Slide 26 of 35
  27. 27. PaSern matching in CλaSH Example -- generate clk enable signal if sclSync then do cnt .= clkCnt clkEn .= True else if _slaveWait then do clkEn .= False else do cnt -= 1 clkEn .= False -- generate bus status controller zoom busState (busStatusCtrl clkCnt cmd sdaChk isdaOen _clkEn cState i2ci) Slide 27 of 35
  28. 28. PaSern matching in CλaSH Example -- generate clk enable signal if sclSync then do cnt .= clkCnt clkEn .= True else if _slaveWait then do clkEn .= False else do cnt -= 1 clkEn .= False -- generate bus status controller zoom busState (busStatusCtrl clkCnt cmd sdaChk isdaOen _clkEn cState i2ci) Slide 28 of 35
  29. 29. Demo Slide 29 of 35
  30. 30. What isn’t working • GADT paSern matching • Irreducible recursive func5ons cannot be translated • Compiler is “really” slow and tends to eat up memory (8gb or over runs happen) – Efficient code as an aperthought doesn’t work – Quadra5c in the size of the let-­‐binding • Finding the right idiom for specifying hardware in Haskell Slide 30 of 35
  31. 31. Future Work • Inline HO-­‐func5ons instead of specialisa5on • Use a dependently-­‐typed core to support e.g. hardware specifica5ons using Idris. – How to merge with GHC’s open type families? • Get my ring-­‐solver in good shape for inclusion in GHC 7.10 • Make the compiler faster: – FlaSen MTL stack – Be more efficient with binders (perhaps use another library) – Make term type a triple of: (term,type,free variables) Slide 31 of 35
  32. 32. Conclusions • GHC API enables lots of fun projects and isn’t that scary. • Use CλaSH instead of Lava when you care about paSern matching. • S5il need to find an idioma5c way to write hardware in Haskell • Stop wri5ng VHDL/Verilog, use Haskell; CλaSH will do the rest. Slide 32 of 35
  33. 33. Ques5ons? cabal install clash-ghc Slide 33 of 35
  34. 34. Extensions used by the Prelude other-extensions: DataKinds DefaultSignatures DeriveDataTypeable FlexibleContexts GADTs GeneralizedNewtypeDeriving KindSignatures MagicHash MultiParamTypeClasses ScopedTypeVariables StandaloneDeriving TemplateHaskell TupleSections TypeFamilies TypeOperators UndecidableInstances Slide 34 of 35
  35. 35. Disabled GHC Op5miza5ons Name Reason Opt_SpecConstr Creates local func5ons: normal form does not have them Opt_DoEtaReduc5on We want eta-­‐expansion Opt_Pedan5cBoSoms Stops eta-­‐expansion through case-­‐expressions Slide 35 of 35

×