22b1d7f35e9be56bd69465f7e2a51da3b909cd28
[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, Mux
6
7 from nmutil.pipemodbase import PipeModBase
8 from ieee754.fpcommon.fpbase import FPNumBaseRecord, FPRoundingMode
9 from ieee754.fpcommon.getop import FPPipeContext
10 from ieee754.fpcommon.postnormalise import FPNorm1Data
11
12
13 class FPRoundData:
14
15 def __init__(self, pspec):
16 width = pspec.width
17 self.z = FPNumBaseRecord(width, False, name="z")
18 self.ctx = FPPipeContext(pspec)
19 self.muxid = self.ctx.muxid
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 self.rm = Signal(FPRoundingMode, reset=FPRoundingMode.DEFAULT)
25 """rounding mode"""
26
27 def eq(self, i):
28 ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
29 self.ctx.eq(i.ctx), self.rm.eq(i.rm)]
30 return ret
31
32
33 class FPRoundMod(PipeModBase):
34
35 def __init__(self, pspec):
36 super().__init__(pspec, "roundz")
37
38 def ispec(self):
39 return FPNorm1Data(self.pspec)
40
41 def ospec(self):
42 return FPRoundData(self.pspec)
43
44 def elaborate(self, platform):
45 m = Module()
46 comb = m.d.comb
47
48 comb += self.o.eq(self.i) # copies muxid, z, out_do_z
49 im = self.i.z.m
50 ie = self.i.z.e
51 msb1s = Signal(reset_less=True)
52 comb += msb1s.eq(self.i.z.m.all()) # all 1s
53 comb += self.o.z.m.eq(Mux(self.i.roundz, im+1, im)) # mantissa up
54 comb += self.o.z.e.eq(Mux(msb1s & self.i.roundz, ie + 1, ie)) # exp up
55
56 return m