1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Cat
6 from nmigen
.cli
import main
10 def __init__(self
, width
):
13 self
.in_a
= Signal(width
)
14 self
.in_a_stb
= Signal()
15 self
.in_a_ack
= Signal()
17 self
.in_b
= Signal(width
)
18 self
.in_b_stb
= Signal()
19 self
.in_b_ack
= Signal()
21 self
.out_z
= Signal(width
)
22 self
.out_z_stb
= Signal()
23 self
.out_z_ack
= Signal()
25 s_out_z_stb
= Signal()
26 s_out_z
= Signal(width
)
30 def get_fragment(self
, platform
):
34 a
= Signal(self
.width
)
35 b
= Signal(self
.width
)
36 z
= Signal(self
.width
)
39 a_m
= Signal(27) # ??? seems to be 1 bit extra??
40 b_m
= Signal(27) # ??? seems to be 1 bit extra??
64 with m
.State("get_a"):
65 with m
.If((self
.in_a_ack
) & (self
.in_a_stb
)):
72 m
.d
.sync
+= self
.in_a_ack
.eq(1)
77 with m
.State("get_b"):
78 with m
.If((self
.in_b_ack
) & (self
.in_b_stb
)):
85 m
.d
.sync
+= self
.in_b_ack
.eq(1)
88 # unpacks operands into sign, mantissa and exponent
90 with m
.State("unpack"):
91 m
.next
= "special_cases"
94 a_m
.eq(Cat(0, 0, 0, a
[0:23])),
95 b_m
.eq(Cat(0, 0, 0, b
[0:23])),
96 # exponent (take off exponent bias, here)
97 a_e
.eq(Cat(a
[23:31]) - 127),
98 b_e
.eq(Cat(b
[23:31]) - 127),
105 # special cases: NaNs, infs, zeros, denormalised
107 with m
.State("special_cases"):
109 # if a is NaN or b is NaN return NaN
110 with m
.If(((a_e
== 128) & (a_m
!= 0)) | \
111 ((b_e
== 128) & (b_m
!= 0))):
114 z
[31].eq(1), # sign: 1
115 z
[23:31].eq(255), # exp: 0b11111...
116 z
[22].eq(1), # mantissa top bit: 1
117 z
[0:22].eq(0) # mantissa rest: 0b0000...
120 # if a is inf return inf (or NaN)
121 with m
.Elif(a_e
== 128):
124 z
[31].eq(a_s
), # sign: a_s
125 z
[23:31].eq(255), # exp: 0b11111...
126 z
[0:23].eq(0) # mantissa rest: 0b0000...
128 # if a is inf and signs don't match return NaN
129 with m
.If((b_e
== 128) & (a_s
!= b_s
)):
131 z
[31].eq(b_s
), # sign: b_s
132 z
[23:31].eq(255), # exp: 0b11111...
133 z
[22].eq(1), # mantissa top bit: 1
134 z
[0:22].eq(0) # mantissa rest: 0b0000...
136 # if b is inf return inf
137 with m
.Elif(b_e
== 128):
140 z
[31].eq(b_s
), # sign: b_s
141 z
[23:31].eq(255), # exp: 0b11111...
142 z
[0:23].eq(0) # mantissa rest: 0b0000...
145 # if a is zero and b zero return signed-a/b
146 with m
.Elif(((a_e
== -127) & (a_m
== 0)) & \
147 ((b_e
== -127) & (b_m
== 0))):
150 z
[31].eq(a_s
& b_s
), # sign: a/b_s
151 z
[23:31].eq(b_e
[0:8] + 127), # exp: b_e (plus bias)
152 z
[0:23].eq(b_m
[3:26]) # mantissa: b_m top bits
155 # if a is zero return b
156 with m
.Elif((a_e
== -127) & (a_m
== 0)):
159 z
[31].eq(b_s
), # sign: a/b_s
160 z
[23:31].eq(b_e
[0:8] + 127), # exp: b_e (plus bias)
161 z
[0:23].eq(b_m
[3:26]) # mantissa: b_m top bits
164 # if b is zero return a
165 with m
.Elif((b_e
== -127) & (b_m
== 0)):
168 z
[31].eq(a_s
), # sign: a/b_s
169 z
[23:31].eq(a_e
[0:8] + 127), # exp: a_e (plus bias)
170 z
[0:23].eq(a_m
[3:26]) # mantissa: a_m top bits
173 # Denormalised Number checks
176 # denormalise a check
177 with m
.If(a_e
== -127):
178 m
.d
.sync
+= a_e
.eq(-126) # limit a exponent
180 m
.d
.sync
+= a_m
[26].eq(1) # set highest mantissa bit
181 # denormalise b check
182 with m
.If(b_e
== -127):
183 m
.d
.sync
+= b_e
.eq(-126) # limit b exponent
185 m
.d
.sync
+= b_m
[26].eq(1) # set highest mantissa bit
190 with m
.State("add_0"):
192 m
.d
.sync
+= z_e
.eq(a_e
)
193 # same-sign (both negative or both positive) add mantissas
194 with m
.If(a_s
== b_s
):
199 # a mantissa greater than b, use a
200 with m
.Else(a_m
>= b_m
):
205 # b mantissa greater than a, use b
212 with m
.State("add_1"):
213 m
.next
= "normalise_1"
219 round_bit
.eq(tot
[2]),
220 sticky
.eq(tot
[1] | tot
[0]),
228 round_bit
.eq(tot
[1]),
234 always @(posedge clk)
242 if (s_in_a_ack && in_a_stb) begin
252 if (s_in_b_ack && in_b_stb) begin
261 a_m <= {a[22 : 0], 3'd0};
262 b_m <= {b[22 : 0], 3'd0};
263 a_e <= a[30 : 23] - 127;
264 b_e <= b[30 : 23] - 127;
267 state <= special_cases;
272 //if a is NaN or b is NaN return NaN
273 if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin
279 //if a is inf return inf
280 end else if (a_e == 128) begin
284 //if a is inf and signs don't match return nan
285 if ((b_e == 128) && (a_s != b_s)) begin
292 //if b is inf return inf
293 end else if (b_e == 128) begin
298 //if a is zero return b
299 end else if ((($signed(a_e) == -127) && (a_m == 0)) && (($signed(b_e) == -127) && (b_m == 0))) begin
301 z[30:23] <= b_e[7:0] + 127;
302 z[22:0] <= b_m[26:3];
304 //if a is zero return b
305 end else if (($signed(a_e) == -127) && (a_m == 0)) begin
307 z[30:23] <= b_e[7:0] + 127;
308 z[22:0] <= b_m[26:3];
310 //if b is zero return a
311 end else if (($signed(b_e) == -127) && (b_m == 0)) begin
313 z[30:23] <= a_e[7:0] + 127;
314 z[22:0] <= a_m[26:3];
317 //Denormalised Number
318 if ($signed(a_e) == -127) begin
323 //Denormalised Number
324 if ($signed(b_e) == -127) begin
335 if ($signed(a_e) > $signed(b_e)) begin
338 b_m[0] <= b_m[0] | b_m[1];
339 end else if ($signed(a_e) < $signed(b_e)) begin
342 a_m[0] <= a_m[0] | a_m[1];
351 if (a_s == b_s) begin
355 if (a_m >= b_m) begin
372 sticky <= tot[1] | tot[0];
380 state <= normalise_1;
385 if (z_m[23] == 0 && $signed(z_e) > -126) begin
392 state <= normalise_2;
398 if ($signed(z_e) < -126) begin
403 sticky <= sticky | round_bit;
411 if (guard && (round_bit | sticky | z_m[0])) begin
413 if (z_m == 24'hffffff) begin
422 z[22 : 0] <= z_m[22:0];
423 z[30 : 23] <= z_e[7:0] + 127;
425 if ($signed(z_e) == -126 && z_m[23] == 0) begin
428 if ($signed(z_e) == -126 && z_m[23:0] == 24'h0) begin
429 z[31] <= 1'b0; // FIX SIGN BUG: -a + a = +0.
431 //if overflow occurs, return inf
432 if ($signed(z_e) > 127) begin
444 if (s_out_z_stb && out_z_ack) begin
460 assign in_a_ack = s_in_a_ack;
461 assign in_b_ack = s_in_b_ack;
462 assign out_z_stb = s_out_z_stb;
463 assign out_z = s_out_z;
468 if __name__
== "__main__":
469 alu
= FPADD(width
=32)
471 alu
.in_a
, alu
.in_a_stb
, alu
.in_a_ack
,
472 alu
.in_b
, alu
.in_b_stb
, alu
.in_b_ack
,
473 alu
.out_z
, alu
.out_z_stb
, alu
.out_z_ack
,