4d54c98dffb813f2ab4999576cd94d89f1be863e
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
25 z
= FPNum(self
.width
, False)
27 tot
= Signal(28) # sticky/round/guard bits, 23 result, 1 overflow
33 with m
.State("get_a"):
35 m
.d
.sync
+= s
.in_a
.ack
.eq(1)
36 with m
.If(s
.in_a
.ack
& in_a
.stb
):
42 with m
.State("get_b"):
44 m
.d
.sync
+= s
.in_b
.ack
.eq(1)
45 with m
.If(s
.in_b
.ack
& in_b
.stb
):
51 with m
.State("unpack"):
52 m
.next
+= "special_cases"
56 a
.e
.eq(a
[23:31] - 127),
57 b
.e
.eq(b
[23:31] - 127),
62 with m
.State("special_cases"):
63 m
.next
= "normalise_a"
64 #if a or b is NaN return NaN
65 with m
.If(a
.is_nan() | b
.is_nan()):
68 #if a is inf return inf
69 with m
.Elif(a
.is_inf()):
72 #if b is zero return NaN
73 with m
.If(b
.is_zero()):
75 #if b is inf return inf
76 with m
.Elif(b
.is_inf()):
79 #if a is zero return NaN
80 with m
.If(a
.is_zero()):
83 #if a is zero return zero
84 with m
.Elif(a
.is_zero()):
87 #if b is zero return zero
88 with m
.Elif(b
.is_zero()):
91 # Denormalised Number checks
93 m
.next
= "normalise_a"
94 self
.denormalise(m
, a
)
95 self
.denormalise(m
, b
)
100 with m
.State("normalise_a"):
101 self
.op_normalise(m
, a
, "normalise_b")
106 with m
.State("normalise_b"):
107 self
.op_normalise(m
, b
, "multiply_0")
114 //if a is NaN or b is NaN return NaN
115 if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin
121 //if a is inf return inf
122 end else if (a_e == 128) begin
126 //if b is zero return NaN
127 if (($signed(b_e) == -127) && (b_m == 0)) begin
134 //if b is inf return inf
135 end else if (b_e == 128) begin
139 //if a is zero return NaN
140 if (($signed(a_e) == -127) && (a_m == 0)) begin
147 //if a is zero return zero
148 end else if (($signed(a_e) == -127) && (a_m == 0)) begin
153 //if b is zero return zero
154 end else if (($signed(b_e) == -127) && (b_m == 0)) begin
161 //Denormalised Number
162 if ($signed(a_e) == -127) begin
167 //Denormalised Number
168 if ($signed(b_e) == -127) begin
173 state <= normalise_a;
180 state <= normalise_b;
200 z_e <= a_e + b_e + 1;
201 product <= a_m * b_m * 4;
207 z_m <= product[49:26];
208 guard <= product[25];
209 round_bit <= product[24];
210 sticky <= (product[23:0] != 0);
211 state <= normalise_1;
216 if (z_m[23] == 0) begin
223 state <= normalise_2;
229 if ($signed(z_e) < -126) begin
234 sticky <= sticky | round_bit;
242 if (guard && (round_bit | sticky | z_m[0])) begin
244 if (z_m == 24'hffffff) begin
253 z[22 : 0] <= z_m[22:0];
254 z[30 : 23] <= z_e[7:0] + 127;
256 if ($signed(z_e) == -126 && z_m[23] == 0) begin
259 //if overflow occurs, return inf
260 if ($signed(z_e) > 127) begin
272 if (s_output_z_stb && output_z_ack) begin