1 # IEEE Floating Point Multiplier
3 from nmigen
import Module
, Signal
, Cat
, Mux
4 from nmigen
.cli
import main
, verilog
7 from nmutil
.pipemodbase
import PipeModBase
8 from ieee754
.fpcommon
.fpbase
import FPNumBase
9 from ieee754
.fpcommon
.getop
import FPPipeContext
10 from ieee754
.fpcommon
.msbhigh
import FPMSBHigh
11 from ieee754
.fpcommon
.denorm
import FPSCData
12 from ieee754
.fpcommon
.postcalc
import FPPostCalcData
15 class FPAlignModSingle(PipeModBase
):
17 def __init__(self
, pspec
, e_extra
=False):
18 self
.e_extra
= e_extra
19 super().__init
__(pspec
, "align")
22 return FPSCData(self
.pspec
, False)
25 return FPSCData(self
.pspec
, False)
27 def elaborate(self
, platform
):
31 self
.o
.a
.m
.name
= "o_a_m"
32 self
.o
.b
.m
.name
= "o_b_m"
34 m
.submodules
.norm1_insel_a
= insel_a
= FPNumBase(self
.i
.a
)
35 m
.submodules
.norm1_insel_b
= insel_b
= FPNumBase(self
.i
.b
)
36 insel_a
.m
.name
= "i_a_m"
37 insel_b
.m
.name
= "i_b_m"
39 # FPMSBHigh makes sure that the MSB is HI (duh).
40 # it does so (in a single cycle) by counting the leading zeros
41 # and performing a shift on the mantissa. the same count is then
42 # subtracted from the exponent.
43 mwid
= self
.o
.z
.m_width
44 msb_a
= FPMSBHigh(mwid
, len(insel_a
.e
))
45 msb_b
= FPMSBHigh(mwid
, len(insel_b
.e
))
46 m
.submodules
.norm_pe_a
= msb_a
47 m
.submodules
.norm_pe_b
= msb_b
49 # connect to msb_a/b module
50 comb
+= msb_a
.m_in
.eq(insel_a
.m
)
51 comb
+= msb_a
.e_in
.eq(insel_a
.e
)
52 comb
+= msb_b
.m_in
.eq(insel_b
.m
)
53 comb
+= msb_b
.e_in
.eq(insel_b
.e
)
55 # copy input to output sign
56 comb
+= self
.o
.a
.s
.eq(insel_a
.s
)
57 comb
+= self
.o
.b
.s
.eq(insel_b
.s
)
59 # normalisation increase/decrease conditions
60 decrease_a
= Signal(reset_less
=True)
61 decrease_b
= Signal(reset_less
=True)
62 comb
+= decrease_a
.eq(insel_a
.m_msbzero
)
63 comb
+= decrease_b
.eq(insel_b
.m_msbzero
)
65 # ok this is near-identical to FPNorm: use same class (FPMSBHigh)
67 self
.o
.a
.e
.eq(Mux(decrease_a
, msb_a
.e_out
, insel_a
.e
)),
68 self
.o
.a
.m
.eq(Mux(decrease_a
, msb_a
.m_out
, insel_a
.m
))
71 self
.o
.b
.e
.eq(Mux(decrease_b
, msb_b
.e_out
, insel_b
.e
)),
72 self
.o
.b
.m
.eq(Mux(decrease_b
, msb_b
.m_out
, insel_b
.m
))
75 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)
76 comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
77 comb
+= self
.o
.oz
.eq(self
.i
.oz
)