deb9ffff803c2c0fc64afa6b01acf245ace196b0
1 from nmigen
import Module
, Signal
2 from nmigen
.cli
import main
, verilog
4 from fpbase
import FPNum
, FPOp
, Overflow
, FPBase
9 def __init__(self
, width
):
13 self
.in_a
= FPOp(width
)
14 self
.in_b
= FPOp(width
)
15 self
.out_z
= FPOp(width
)
17 def get_fragment(self
, platform
=None):
18 """ creates the HDL code-fragment for FPMUL
23 a
= FPNum(self
.width
, False)
24 b
= FPNum(self
.width
, False)
25 z
= FPNum(self
.width
, False)
27 mw
= (self
.width
)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
37 with m
.State("get_a"):
38 self
.get_op(m
, self
.in_a
, a
, "get_b")
43 with m
.State("get_b"):
44 self
.get_op(m
, self
.in_b
, b
, "special_cases")
49 with m
.State("special_cases"):
50 m
.next
= "normalise_a"
51 #if a or b is NaN return NaN
52 with m
.If(a
.is_nan() | b
.is_nan()):
55 #if a is inf return inf
56 with m
.Elif(a
.is_inf()):
59 #if b is zero return NaN
60 with m
.If(b
.is_zero()):
62 #if b is inf return inf
63 with m
.Elif(b
.is_inf()):
66 #if a is zero return NaN
67 with m
.If(a
.is_zero()):
70 #if a is zero return zero
71 with m
.Elif(a
.is_zero()):
74 #if b is zero return zero
75 with m
.Elif(b
.is_zero()):
78 # Denormalised Number checks
80 m
.next
+= "normalise_a"
81 self
.denormalise(m
, a
)
82 self
.denormalise(m
, b
)
87 with m
.State("normalise_a"):
88 self
.op_normalise(m
, a
, "normalise_b")
93 with m
.State("normalise_b"):
94 self
.op_normalise(m
, b
, "multiply_0")
97 with m
.State("multiply_0"):
98 m
.next
+= "multiply_1"
101 z
.e
.eq(a
.e
+ b
.e
+ 1),
102 product
.eq(a
.m
* b
.m
* 4)
106 with m
.State("multiply_1"):
107 m
.next
+= "normalise_1"
109 z
.m
.eq(product
[26:50]),
110 guard
.eq(product
[25]),
111 round_bit
.eq(product
[24]),
112 sticky
.eq(product
[0:23] != 0)
116 # First stage of normalisation.
117 with m
.State("normalise_1"):
118 self
.normalise_1(m
, z
, of
, "normalise_2")
121 # Second stage of normalisation.
123 with m
.State("normalise_2"):
124 self
.normalise_2(m
, z
, of
, "round")
129 with m
.State("round"):
130 self
.roundz(m
, z
, of
, "corrections")
135 with m
.State("corrections"):
136 self
.corrections(m
, z
, "pack")
140 with m
.State("pack"):
141 self
.pack(m
, z
, "put_z")
146 with m
.State("put_z"):
147 self
.put_z(m
, z
, self
.out_z
, "get_a")
154 //if a is NaN or b is NaN return NaN
155 if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin
161 //if a is inf return inf
162 end else if (a_e == 128) begin
166 //if b is zero return NaN
167 if (($signed(b_e) == -127) && (b_m == 0)) begin
174 //if b is inf return inf
175 end else if (b_e == 128) begin
179 //if a is zero return NaN
180 if (($signed(a_e) == -127) && (a_m == 0)) begin
187 //if a is zero return zero
188 end else if (($signed(a_e) == -127) && (a_m == 0)) begin
193 //if b is zero return zero
194 end else if (($signed(b_e) == -127) && (b_m == 0)) begin
201 //Denormalised Number
202 if ($signed(a_e) == -127) begin
207 //Denormalised Number
208 if ($signed(b_e) == -127) begin
213 state <= normalise_a;
220 state <= normalise_b;
240 z_e <= a_e + b_e + 1;
241 product <= a_m * b_m * 4;
247 z_m <= product[49:26];
248 guard <= product[25];
249 round_bit <= product[24];
250 sticky <= (product[23:0] != 0);
251 state <= normalise_1;
256 if (z_m[23] == 0) begin
263 state <= normalise_2;
269 if ($signed(z_e) < -126) begin
274 sticky <= sticky | round_bit;
282 if (guard && (round_bit | sticky | z_m[0])) begin
284 if (z_m == 24'hffffff) begin
293 z[22 : 0] <= z_m[22:0];
294 z[30 : 23] <= z_e[7:0] + 127;
296 if ($signed(z_e) == -126 && z_m[23] == 0) begin
301 if ($signed(z_e) > 127) begin
313 if (s_output_z_stb && output_z_ack) begin
321 if __name__
== "__main__":
322 alu
= FPMUL(width
=32)
323 main(alu
, ports
=alu
.in_a
.ports() + alu
.in_b
.ports() + alu
.out_z
.ports())