add identifying name to FPNumBaseRecord
[ieee754fpu.git] / src / ieee754 / fpcommon / roundz.py
1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
3 # 2013-12-12
4
5 from nmigen import Module, Signal, Elaboratable
6 from nmigen.cli import main, verilog
7
8 from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
9 from ieee754.fpcommon.fpbase import FPState
10 from ieee754.fpcommon.getop import FPPipeContext
11 from .postnormalise import FPNorm1Data
12
13
14 class FPRoundData:
15
16 def __init__(self, pspec):
17 width = pspec.width
18 self.z = FPNumBaseRecord(width, False, name="z")
19 self.ctx = FPPipeContext(pspec)
20 self.muxid = self.ctx.muxid
21 # pipeline bypass [data comes from specialcases]
22 self.out_do_z = Signal(reset_less=True)
23 self.oz = Signal(width, reset_less=True)
24
25 def eq(self, i):
26 ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
27 self.ctx.eq(i.ctx)]
28 return ret
29
30
31 class FPRoundMod(Elaboratable):
32
33 def __init__(self, pspec):
34 self.pspec = pspec
35 self.i = self.ispec()
36 self.out_z = self.ospec()
37
38 def ispec(self):
39 return FPNorm1Data(self.pspec)
40
41 def ospec(self):
42 return FPRoundData(self.pspec)
43
44 def process(self, i):
45 return self.out_z
46
47 def setup(self, m, i):
48 m.submodules.roundz = self
49 m.d.comb += self.i.eq(i)
50
51 def elaborate(self, platform):
52 m = Module()
53 m.d.comb += self.out_z.eq(self.i) # copies muxid, z, out_do_z
54 with m.If(~self.i.out_do_z): # bypass wasn't enabled
55 with m.If(self.i.roundz):
56 m.d.comb += self.out_z.z.m.eq(self.i.z.m + 1) # mantissa up
57 with m.If(self.i.z.m == self.i.z.m1s): # all 1s
58 # exponent up
59 m.d.comb += self.out_z.z.e.eq(self.i.z.e + 1)
60
61 return m
62
63
64 class FPRound(FPState):
65
66 def __init__(self, width, id_wid):
67 FPState.__init__(self, "round")
68 self.mod = FPRoundMod(width)
69 self.out_z = self.ospec()
70
71 def ispec(self):
72 return self.mod.ispec()
73
74 def ospec(self):
75 return self.mod.ospec()
76
77 def setup(self, m, i):
78 """ links module to inputs and outputs
79 """
80 self.mod.setup(m, i)
81
82 self.idsync(m)
83 m.d.sync += self.out_z.eq(self.mod.out_z)
84 m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
85
86 def action(self, m):
87 m.next = "corrections"