import Lava import Lava.Patterns import Lava.Arithmetic type Bit = Signal Bool -- convenient abbreviation -- Zero detect Exercise ------------------------------------------------------ zero_detect as = inv nz where nz = nz_detect0 as nz_detect0 [] = low nz_detect0 (a:as) = out where out = or2(a,out2) out2 = nz_detect0 as nz_detect1 [] = low nz_detect1 [a] = a nz_detect1 as = out where (as1,as2) = halveList as out1 = nz_detect1 as1 out2 = nz_detect1 as2 out = or2(out1,out2) nz_detect2 [] = low nz_detect2 [a] = a nz_detect2 as = circ as where circ = halveList ->- (nz_detect2 -|- nz_detect2) ->- or2 -- capturing the pattern as a reusable combinator binTree :: ((a,a) -> a) -> [a] -> a binTree c [] = error "binTree of empty list" binTree c [a] = a binTree c as = circ as where circ = halveList ->- (binTree c -|- binTree c) ->- c nz_detect3 = binTree or2 -- Note that gates are also generic (called andl, xorl etc. (l for list) -- (but generated netlist uses 2 input gates nz_detect4 = orl -- Simple delay analysis ------------------------------------------------------- -- Depth computations ldepth :: (Signal Int, Signal Int) -> Signal Int ldepth (a,b) = max a b + 1 dtstTree n = simulate (binTree ldepth) (replicate n 0) dtstT n = map dtstTree [1..n] -- from Lecture 2 red :: ((a,b) -> a) -> (a, [b]) -> a red f (a,[]) = a red f (a, (b:bs)) = red f (f(a,b), bs) lin f (a:as) = red f (a,as) lin _ [] = error "lin: empty list" dtstLin n = simulate (lin ldepth) (replicate n 0) dtstL n = map dtstLin [1..n] -- modelling delay in a full adder --------------------------------------------- fAddI (a1s, a2s, a3s, a1c, a2c, a3c) (a1,(a2,a3)) = (s,cout) where s = maximum [a1s+a1, a2s+a2, a3s+a3] cout = maximum [a1c+a1, a2c+a2, a3c+a3] fI = fAddI (20,20,10,10,10,10) -- from first lecture but generalising the type! rcAdder2 :: ((a,(a,a)) -> (a,a)) -> (a,([a],[a])) -> ([a], a) rcAdder2 fadd (c0, (as, bs)) = (sum, cOut) where (sum, cOut) = row fadd (c0, zipp (as,bs)) rcdeltst1 = simulate (rcAdder2 fI) (0 :: Signal Int, (replicate 10 0, replicate 10 0)) -- For circuits without feedback, one can also just compute delays -- directly in Haskell as below. One shouldn't try to mix the two approaches :) -- rcdeltst = rcAdder2 fI (0, (replicate 10 0, replicate 10 0)) -- This general approach is called Non Standard Intrpretation -- replacing -- circuit components by others that do analyses, and then running (simulating) -- the circuit to get analysis results.