a0b568689433b54b90adfc3d8d9ceb7effbb37bd
[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 FPBaseData
11 from .postnormalise import FPNorm1Data
12
13
14 class FPRoundData:
15
16 def __init__(self, width, pspec):
17 self.z = FPNumBaseRecord(width, False)
18 self.ctx = FPBaseData(width, pspec)
19 self.mid = self.ctx.mid
20 # pipeline bypass [data comes from specialcases]
21 self.out_do_z = Signal(reset_less=True)
22 self.oz = Signal(width, reset_less=True)
23
24 def eq(self, i):
25 ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
26 self.ctx.eq(i.ctx)]
27 return ret
28
29
30 class FPRoundMod(Elaboratable):
31
32 def __init__(self, width, pspec):
33 self.width = width
34 self.pspec = pspec
35 self.i = self.ispec()
36 self.out_z = self.ospec()
37
38 def ispec(self):
39 return FPNorm1Data(self.width, self.pspec)
40
41 def ospec(self):
42 return FPRoundData(self.width, 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 mid, 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 m.d.comb += self.out_z.z.e.eq(self.i.z.e + 1) # exponent up
59
60 return m
61
62
63 class FPRound(FPState):
64
65 def __init__(self, width, id_wid):
66 FPState.__init__(self, "round")
67 self.mod = FPRoundMod(width)
68 self.out_z = self.ospec()
69
70 def ispec(self):
71 return self.mod.ispec()
72
73 def ospec(self):
74 return self.mod.ospec()
75
76 def setup(self, m, i):
77 """ links module to inputs and outputs
78 """
79 self.mod.setup(m, i)
80
81 self.idsync(m)
82 m.d.sync += self.out_z.eq(self.mod.out_z)
83 m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
84
85 def action(self, m):
86 m.next = "corrections"