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