Add another higher order testcase, highordtest2.
[matthijs/master-project/cλash.git] / Adders.hs
1 module Adders where
2 import Bits
3 import qualified Sim
4 import Language.Haskell.Syntax
5 import qualified Data.TypeLevel as TypeLevel
6 import qualified Data.Param.FSVec as FSVec
7
8 mainIO f = Sim.simulateIO (Sim.stateless f) ()
9
10 -- This function is from Sim.hs, but we redefine it here so it can get inlined
11 -- by default.
12 stateless :: (i -> o) -> (i -> () -> ((), o))
13 stateless f = \i s -> (s, f i)
14
15 show_add f = do print ("Sum:   " ++ (displaysigs s)); print ("Carry: " ++ (displaysig c))
16   where
17     a = [High, High, High, High]
18     b = [Low, Low, Low, High]
19     (s, c) = f (a, b)
20
21 mux2 :: Bit -> (Bit, Bit) -> Bit
22 mux2 Low (a, b) = a
23 mux2 High (a, b) = b
24
25 -- Not really an adder, but this is nice minimal hardware description
26 wire :: Bit -> Bit
27 wire a = a
28
29 bus :: (TypeLevel.Pos len) => BitVec len -> BitVec len
30 bus v = v
31
32 bus_4 :: BitVec TypeLevel.D4 -> BitVec TypeLevel.D4
33 bus_4 v = v
34
35 {-
36 inv_n :: (Pos len) => BitVec len -> BitVec len
37 inv_n v =
38   --FSVec.map hwnot v
39   inv_n_rec v
40
41 class Inv vec where
42   inv_n_rec :: vec -> vec
43
44 instance (Pos len) => Inv (BitVec len) where
45   inv_n_rec v = 
46     h FSVec.+> t
47     where
48       h = FSVec.head v
49       t = FSVec.tail v
50
51 instance Inv (BitVec D0) where
52   inv_n_rec v = v
53 -}
54 -- Not really an adder either, but a slightly more complex example
55 inv :: Bit -> Bit
56 inv a = let r = hwnot a in r
57
58 -- Not really an adder either, but a slightly more complex example
59 invinv :: Bit -> Bit
60 invinv a = hwnot (hwnot a)
61
62 -- Not really an adder either, but a slightly more complex example
63 dup :: Bit -> (Bit, Bit)
64 dup a = (a, a)
65
66 -- Not really an adder either, but a simple stateful example (D-flipflop)
67 dff :: Bit -> Bit -> (Bit, Bit)
68 dff d s = (s', q)
69   where
70     q = s
71     s' = d
72
73 type ShifterState = (Bit, Bit, Bit, Bit)
74 shifter :: Bit -> ShifterState -> (ShifterState, Bit)
75 shifter i (a, b, c, d) =
76   (s', d)
77   where
78     s' = (i, a, b, c)
79
80 {-# NOINLINE shifter_en #-}
81 shifter_en :: Bit -> Bit-> ShifterState -> (ShifterState, Bit)
82 shifter_en High i (a, b, c, d) =
83   (s', d)
84   where
85     s' = (i, a, b, c)
86
87 shifter_en Low i s@(a, b, c, d) =
88   (s, d)
89
90 -- Two multiplexed shifters
91 type ShiftersState = (ShifterState, ShifterState)
92 shifters :: Bit -> Bit -> ShiftersState -> (ShiftersState, Bit)
93 shifters sel i (sa, sb) =
94   (s', out)
95   where
96     (sa', outa) = shifter_en sel i sa
97     (sb', outb) = shifter_en (hwnot sel) i sb
98     s' = (sa', sb')
99     out = if sel == High then outa else outb
100
101 -- Combinatoric stateless no-carry adder
102 -- A -> B -> S
103 no_carry_adder :: (Bit, Bit) -> Bit
104 no_carry_adder (a, b) = a `hwxor` b
105
106 -- Combinatoric stateless half adder
107 -- A -> B -> (S, C)
108 half_adder :: (Bit, Bit) -> (Bit, Bit)
109 {-# NOINLINE half_adder #-}
110 half_adder (a, b) = 
111   ( a `hwxor` b, a `hwand` b )
112
113 -- Combinatoric stateless full adder
114 -- (A, B, C) -> (S, C)
115 full_adder :: (Bit, Bit, Bit) -> (Bit, Bit)
116 full_adder (a, b, cin) = (s, c)
117   where
118     (s1, c1) = half_adder(a, b)
119     (s, c2)  = half_adder(s1, cin)
120     c        = c1 `hwor` c2
121
122 sfull_adder = stateless full_adder
123
124 -- Four bit adder
125 -- Explicit version
126 -- [a] -> [b] -> ([s], cout)
127 exp_adder :: ([Bit], [Bit]) -> ([Bit], Bit)
128
129 exp_adder ([a3,a2,a1,a0], [b3,b2,b1,b0]) =
130   ([s3, s2, s1, s0], c3)
131   where
132     (s0, c0) = full_adder (a0, b0, Low)
133     (s1, c1) = full_adder (a1, b1, c0)
134     (s2, c2) = full_adder (a2, b2, c1)
135     (s3, c3) = full_adder (a3, b3, c2)
136
137 -- Any number of bits adder
138 -- Recursive version
139 -- [a] -> [b] -> ([s], cout)
140 rec_adder :: ([Bit], [Bit]) -> ([Bit], Bit)
141
142 rec_adder ([], []) = ([], Low)
143 rec_adder ((a:as), (b:bs)) = 
144   (s : rest, cout)
145   where
146     (rest, cin) = rec_adder (as, bs)
147     (s, cout) = full_adder (a, b, cin)
148
149 foo = id
150 add, sub :: Int -> Int -> Int
151 add a b = a + b
152 sub a b = a - b
153
154 highordtest = \x ->
155   let s = foo x
156   in
157      case s of
158        (a, b) ->
159          case a of
160            High -> add
161            Low -> let
162              op' = case b of
163                 High -> sub
164                 Low -> \c d -> c
165              in
166                 \c d -> op' d c
167
168 highordtest2 = \a b ->
169          case a of
170            High -> \c d -> d
171            Low -> let
172              op' :: Bit -> Bit -> Bit
173              op' = case b of
174                 High -> \c d -> d
175                 Low -> \c d -> c
176              in
177                 \c d -> op' d c
178 -- Four bit adder, using the continous adder below
179 -- [a] -> [b] -> ([s], cout)
180 --con_adder_4 as bs = 
181 --  ([s3, s2, s1, s0], c)
182 --  where
183 --    ((s0, _):(s1, _):(s2, _):(s3, c):_) = con_adder (zip ((reverse as) ++ lows) ((reverse bs) ++ lows))
184
185 -- Continuous sequential version
186 -- Stream a -> Stream b -> Stream (sum, cout)
187 --con_adder :: Stream (Bit, Bit) -> Stream (Bit, Bit)
188
189 -- Forward to con_adder_int, but supply an initial state
190 --con_adder pin =
191 --  con_adder_int pin Low
192
193 -- Stream a -> Stream b -> state -> Stream (s, c)
194 --con_adder_int :: Stream (Bit, Bit) -> Bit -> Stream (Bit, Bit)
195 --con_adder_int ((a,b):rest) cin =
196 --  (s, cout) : con_adder_int rest cout
197 --  where
198 --    (s, cout) = full_adder a b cin
199
200 -- vim: set ts=8 sw=2 sts=2 expandtab: