0c5cb6e5ffdb7d85ede8e41071cf4e3690ef4bd8
[ieee754fpu.git] / src / ieee754 / fpmul / mul1.py
1 # IEEE Floating Point Multiplier
2
3 from nmigen import Module, Signal, Elaboratable
4 from nmigen.cli import main, verilog
5
6 from ieee754.fpcommon.fpbase import FPState
7 from ieee754.fpcommon.postcalc import FPAddStage1Data
8 from .mul0 import FPMulStage0Data
9
10
11 class FPMulStage1Mod(FPState, Elaboratable):
12 """ Second stage of mul: preparation for normalisation.
13 """
14
15 def __init__(self, width, id_wid, op_wid=None):
16 self.width = width
17 self.id_wid = id_wid
18 self.op_wid = op_wid
19 self.i = self.ispec()
20 self.o = self.ospec()
21
22 def ispec(self):
23 return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
24
25 def ospec(self):
26 return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
27
28 def process(self, i):
29 return self.o
30
31 def setup(self, m, i):
32 """ links module to inputs and outputs
33 """
34 m.submodules.mul1 = self
35 #m.submodules.mul1_out_overflow = self.o.of
36
37 m.d.comb += self.i.eq(i)
38
39 def elaborate(self, platform):
40 m = Module()
41 m.d.comb += self.o.z.eq(self.i.z)
42 with m.If(~self.i.out_do_z):
43 mw = self.o.z.m_width
44 m.d.comb += [
45 self.o.z.m.eq(self.i.product[mw+2:]),
46 self.o.of.m0.eq(self.i.product[mw+2]),
47 self.o.of.guard.eq(self.i.product[mw+1]),
48 self.o.of.round_bit.eq(self.i.product[mw]),
49 self.o.of.sticky.eq(self.i.product[0:mw].bool())
50 ]
51
52 m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
53 m.d.comb += self.o.oz.eq(self.i.oz)
54 m.d.comb += self.o.mid.eq(self.i.mid)
55 if self.o.op_wid:
56 m.d.comb += self.o.op.eq(self.i.op)
57
58 return m
59
60
61 class FPMulStage1(FPState):
62
63 def __init__(self, width, id_wid):
64 FPState.__init__(self, "multiply_1")
65 self.mod = FPMulStage1Mod(width)
66 self.out_z = FPNumBaseRecord(width, False)
67 self.out_of = Overflow()
68 self.norm_stb = Signal()
69
70 def setup(self, m, i):
71 """ links module to inputs and outputs
72 """
73 self.mod.setup(m, i)
74
75 m.d.sync += self.norm_stb.eq(0) # sets to zero when not in mul1 state
76
77 m.d.sync += self.out_of.eq(self.mod.out_of)
78 m.d.sync += self.out_z.eq(self.mod.out_z)
79 m.d.sync += self.norm_stb.eq(1)
80
81 def action(self, m):
82 m.next = "normalise_1"
83