1 from nmigen
import Module
, Signal
, Cat
, Mux
, Array
, Const
2 from nmigen
.cli
import main
, verilog
4 from fpbase
import FPNumIn
, FPNumOut
, FPOp
, Overflow
, FPBase
5 from nmigen_add_experiment
import FPState
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
= FPNumIn(None, self
.width
, False)
24 b
= FPNumIn(None, self
.width
, False)
25 z
= FPNumOut(self
.width
, False)
27 mw
= (z
.m_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 #if a or b is NaN return NaN
51 with m
.If(a
.is_nan | b
.is_nan
):
54 #if a is inf return inf
55 with m
.Elif(a
.is_inf
):
57 m
.d
.sync
+= z
.inf(a
.s ^ b
.s
)
58 #if b is zero return NaN
61 #if b is inf return inf
62 with m
.Elif(b
.is_inf
):
64 m
.d
.sync
+= z
.inf(a
.s ^ b
.s
)
65 #if a is zero return NaN
69 #if a is zero return zero
70 with m
.Elif(a
.is_zero
):
72 m
.d
.sync
+= z
.zero(a
.s ^ b
.s
)
73 #if b is zero return zero
74 with m
.Elif(b
.is_zero
):
76 m
.d
.sync
+= z
.zero(a
.s ^ b
.s
)
77 # Denormalised Number checks
79 m
.next
= "normalise_a"
80 self
.denormalise(m
, a
)
81 self
.denormalise(m
, b
)
86 with m
.State("normalise_a"):
87 self
.op_normalise(m
, a
, "normalise_b")
92 with m
.State("normalise_b"):
93 self
.op_normalise(m
, b
, "multiply_0")
96 with m
.State("multiply_0"):
100 z
.e
.eq(a
.e
+ b
.e
+ 1),
101 product
.eq(a
.m
* b
.m
* 4)
105 with m
.State("multiply_1"):
107 m
.next
= "normalise_1"
109 z
.m
.eq(product
[mw
+2:]),
110 of
.guard
.eq(product
[mw
+1]),
111 of
.round_bit
.eq(product
[mw
]),
112 of
.sticky
.eq(product
[0:mw
] != 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.roundz)
131 m
.next
= "corrections"
136 with m
.State("corrections"):
137 self
.corrections(m
, z
, "pack")
141 with m
.State("pack"):
142 self
.pack(m
, z
, "put_z")
147 with m
.State("put_z"):
148 self
.put_z(m
, z
, self
.out_z
, "get_a")
153 if __name__
== "__main__":
154 alu
= FPMUL(width
=32)
155 main(alu
, ports
=alu
.in_a
.ports() + alu
.in_b
.ports() + alu
.out_z
.ports())