1 from nmigen
import Module
, Signal
, Cat
, Mux
, Array
, Const
2 from nmigen
.cli
import main
, verilog
4 from fpbase
import FPNum
, FPOp
, Overflow
, FPBase
7 def __init__(self
, state_from
):
8 self
.state_from
= state_from
10 def set_inputs(self
, inputs
):
12 for k
,v
in inputs
.items():
15 def set_outputs(self
, outputs
):
16 self
.outputs
= outputs
17 for k
,v
in outputs
.items():
26 def __init__(self, width):
30 self.in_a = FPOp(width)
31 self.in_b = FPOp(width)
32 self.out_z = FPOp(width)
34 def get_fragment(self, platform=None):
35 """ creates the HDL code-fragment for FPMUL
40 a = FPNum(self.width, False)
41 b = FPNum(self.width, False)
42 z = FPNum(self.width, False)
44 mw = (z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
54 with m.State("get_a"):
55 self.get_op(m, self.in_a, a, "get_b")
60 with m.State("get_b"):
61 self.get_op(m, self.in_b, b, "special_cases")
66 with m.State("special_cases"):
67 #if a or b is NaN return NaN
68 with m.If(a.is_nan() | b.is_nan()):
71 #if a is inf return inf
72 with m.Elif(a.is_inf()):
74 m.d.sync += z.inf(a.s ^ b.s)
75 #if b is zero return NaN
76 with m.If(b.is_zero()):
78 #if b is inf return inf
79 with m.Elif(b.is_inf()):
81 m.d.sync += z.inf(a.s ^ b.s)
82 #if a is zero return NaN
83 with m.If(a.is_zero()):
86 #if a is zero return zero
87 with m.Elif(a.is_zero()):
89 m.d.sync += z.zero(a.s ^ b.s)
90 #if b is zero return zero
91 with m.Elif(b.is_zero()):
93 m.d.sync += z.zero(a.s ^ b.s)
94 # Denormalised Number checks
96 m.next = "normalise_a"
97 self.denormalise(m, a)
98 self.denormalise(m, b)
103 with m.State("normalise_a"):
104 self.op_normalise(m, a, "normalise_b")
109 with m.State("normalise_b"):
110 self.op_normalise(m, b, "multiply_0")
113 with m.State("multiply_0"):
114 m.next = "multiply_1"
117 z.e.eq(a.e + b.e + 1),
118 product.eq(a.m * b.m * 4)
122 with m.State("multiply_1"):
124 m.next = "normalise_1"
126 z.m.eq(product[mw+2:]),
127 of.guard.eq(product[mw+1]),
128 of.round_bit.eq(product[mw]),
129 of.sticky.eq(product[0:mw] != 0)
133 # First stage of normalisation.
134 with m.State("normalise_1"):
135 self.normalise_1(m, z, of, "normalise_2")
138 # Second stage of normalisation.
140 with m.State("normalise_2"):
141 self.normalise_2(m, z, of, "round")
146 with m.State("round"):
147 self.roundz(m, z, of, "corrections")
152 with m.State("corrections"):
153 self.corrections(m, z, "pack")
157 with m.State("pack"):
158 self.pack(m, z, "put_z")
163 with m.State("put_z"):
164 self.put_z(m, z, self.out_z, "get_a")
169 if __name__ == "__main__":
170 alu = FPMUL(width=32)
171 main(alu, ports=alu.in_a.ports() + alu.in_b.ports() + alu.out_z.ports())