move FPModBase and FPModBaseChain to nmutil
[ieee754fpu.git] / src / ieee754 / fpmul / align.py
1 # IEEE Floating Point Multiplier
2
3 from nmigen import Module, Signal, Cat, Mux
4 from nmigen.cli import main, verilog
5 from math import log
6
7 from nmutil.pipemodbase import FPModBase
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 FPAddStage1Data
13
14
15 class FPAlignModSingle(FPModBase):
16
17 def __init__(self, pspec, e_extra=False):
18 self.e_extra = e_extra
19 super().__init__(pspec, "align")
20
21 def ispec(self):
22 return FPSCData(self.pspec, False)
23
24 def ospec(self):
25 return FPSCData(self.pspec, False)
26
27 def elaborate(self, platform):
28 m = Module()
29 comb = m.d.comb
30
31 self.o.a.m.name = "o_a_m"
32 self.o.b.m.name = "o_b_m"
33
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"
38
39 mwid = self.o.z.m_width
40 msb_a = FPMSBHigh(mwid, len(insel_a.e))
41 msb_b = FPMSBHigh(mwid, len(insel_b.e))
42 m.submodules.norm_pe_a = msb_a
43 m.submodules.norm_pe_b = msb_b
44
45 # connect to msb_a/b module
46 comb += msb_a.m_in.eq(insel_a.m)
47 comb += msb_a.e_in.eq(insel_a.e)
48 comb += msb_b.m_in.eq(insel_b.m)
49 comb += msb_b.e_in.eq(insel_b.e)
50
51 # copy input to output (overridden below)
52 comb += self.o.a.eq(insel_a)
53 comb += self.o.b.eq(insel_b)
54
55 # normalisation increase/decrease conditions
56 decrease_a = Signal(reset_less=True)
57 decrease_b = Signal(reset_less=True)
58 comb += decrease_a.eq(insel_a.m_msbzero)
59 comb += decrease_b.eq(insel_b.m_msbzero)
60
61 # ok this is near-identical to FPNorm: use same class (FPMSBHigh)
62 with m.If(~self.i.out_do_z):
63 with m.If(decrease_a):
64 comb += [
65 self.o.a.e.eq(msb_a.e_out),
66 self.o.a.m.eq(msb_a.m_out),
67 ]
68 with m.If(decrease_b):
69 comb += [
70 self.o.b.e.eq(msb_b.e_out),
71 self.o.b.m.eq(msb_b.m_out),
72 ]
73
74 comb += self.o.ctx.eq(self.i.ctx)
75 comb += self.o.out_do_z.eq(self.i.out_do_z)
76 comb += self.o.oz.eq(self.i.oz)
77
78 return m