switch to exact version of cython
[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 FPFormat, 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(m_extra=False, name="z",
18 fpformat=FPFormat.from_pspec(pspec))
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 self.rm = Signal(FPRoundingMode, reset=FPRoundingMode.DEFAULT)
26 """rounding mode"""
27
28 def eq(self, i):
29 ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
30 self.ctx.eq(i.ctx), self.rm.eq(i.rm)]
31 return ret
32
33
34 class FPRoundMod(PipeModBase):
35
36 def __init__(self, pspec):
37 super().__init__(pspec, "roundz")
38
39 def ispec(self):
40 return FPNorm1Data(self.pspec)
41
42 def ospec(self):
43 return FPRoundData(self.pspec)
44
45 def elaborate(self, platform):
46 m = Module()
47 comb = m.d.comb
48
49 comb += self.o.eq(self.i) # copies muxid, z, out_do_z
50 im = self.i.z.m
51 ie = self.i.z.e
52 msb1s = Signal(reset_less=True)
53 comb += msb1s.eq(self.i.z.m.all()) # all 1s
54 comb += self.o.z.m.eq(Mux(self.i.roundz, im+1, im)) # mantissa up
55 comb += self.o.z.e.eq(Mux(msb1s & self.i.roundz, ie + 1, ie)) # exp up
56
57 return m