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
, 24)
27 tot
= Signal(28) # sticky/round/guard bits, 23 result, 1 overflow
42 if (s_input_a_ack && input_a_stb) begin
52 if (s_input_b_ack && input_b_stb) begin
63 a_e <= a[30 : 23] - 127;
64 b_e <= b[30 : 23] - 127;
67 state <= special_cases;
72 //if a is NaN or b is NaN return NaN
73 if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin
79 //if a is inf return inf
80 end else if (a_e == 128) begin
84 //if b is zero return NaN
85 if (($signed(b_e) == -127) && (b_m == 0)) begin
92 //if b is inf return inf
93 end else if (b_e == 128) begin
97 //if a is zero return NaN
98 if (($signed(a_e) == -127) && (a_m == 0)) begin
105 //if a is zero return zero
106 end else if (($signed(a_e) == -127) && (a_m == 0)) begin
111 //if b is zero return zero
112 end else if (($signed(b_e) == -127) && (b_m == 0)) begin
118 //Denormalised Number
119 if ($signed(a_e) == -127) begin
124 //Denormalised Number
125 if ($signed(b_e) == -127) begin
130 state <= normalise_a;
137 state <= normalise_b;
157 z_e <= a_e + b_e + 1;
158 product <= a_m * b_m * 4;
164 z_m <= product[49:26];
165 guard <= product[25];
166 round_bit <= product[24];
167 sticky <= (product[23:0] != 0);
168 state <= normalise_1;
173 if (z_m[23] == 0) begin
180 state <= normalise_2;
186 if ($signed(z_e) < -126) begin
191 sticky <= sticky | round_bit;
199 if (guard && (round_bit | sticky | z_m[0])) begin
201 if (z_m == 24'hffffff) begin
210 z[22 : 0] <= z_m[22:0];
211 z[30 : 23] <= z_e[7:0] + 127;
213 if ($signed(z_e) == -126 && z_m[23] == 0) begin
216 //if overflow occurs, return inf
217 if ($signed(z_e) > 127) begin
229 if (s_output_z_stb && output_z_ack) begin