add in missing modules
[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
9 from ieee754.fpcommon.fpbase import FPState
10 from .postnormalise import FPNorm1Data
11
12
13 class FPRoundData:
14
15 def __init__(self, width, id_wid):
16 self.z = FPNumBase(width, False)
17 self.out_do_z = Signal(reset_less=True)
18 self.oz = Signal(width, reset_less=True)
19 self.mid = Signal(id_wid, reset_less=True)
20
21 def eq(self, i):
22 return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
23 self.mid.eq(i.mid)]
24
25
26 class FPRoundMod(Elaboratable):
27
28 def __init__(self, width, id_wid):
29 self.width = width
30 self.id_wid = id_wid
31 self.i = self.ispec()
32 self.out_z = self.ospec()
33
34 def ispec(self):
35 return FPNorm1Data(self.width, self.id_wid)
36
37 def ospec(self):
38 return FPRoundData(self.width, self.id_wid)
39
40 def process(self, i):
41 return self.out_z
42
43 def setup(self, m, i):
44 m.submodules.roundz = self
45 m.submodules.round_out_z = self.i.z
46 m.d.comb += self.i.eq(i)
47
48 def elaborate(self, platform):
49 m = Module()
50 m.d.comb += self.out_z.eq(self.i) # copies mid, z, out_do_z
51 with m.If(~self.i.out_do_z):
52 with m.If(self.i.roundz):
53 m.d.comb += self.out_z.z.m.eq(self.i.z.m + 1) # mantissa up
54 with m.If(self.i.z.m == self.i.z.m1s): # all 1s
55 m.d.comb += self.out_z.z.e.eq(self.i.z.e + 1) # exponent up
56
57 return m
58
59
60 class FPRound(FPState):
61
62 def __init__(self, width, id_wid):
63 FPState.__init__(self, "round")
64 self.mod = FPRoundMod(width)
65 self.out_z = self.ospec()
66
67 def ispec(self):
68 return self.mod.ispec()
69
70 def ospec(self):
71 return self.mod.ospec()
72
73 def setup(self, m, i):
74 """ links module to inputs and outputs
75 """
76 self.mod.setup(m, i)
77
78 self.idsync(m)
79 m.d.sync += self.out_z.eq(self.mod.out_z)
80 m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
81
82 def action(self, m):
83 m.next = "corrections"