56c4457d281e9bd3b6ca41eb0ab6009cfe1033a7
[ieee754fpu.git] / src / ieee754 / fpcommon / pack.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
6
7 from nmutil.pipemodbase import PipeModBase
8 from ieee754.fpcommon.fpbase import FPNumBaseRecord, FPNumBase, FPRoundingMode
9 from ieee754.fpcommon.roundz import FPRoundData
10 from ieee754.fpcommon.packdata import FPPackData
11
12
13 class FPPackMod(PipeModBase):
14
15 def __init__(self, pspec):
16 super().__init__(pspec, "pack")
17
18 def ispec(self):
19 return FPRoundData(self.pspec)
20
21 def ospec(self):
22 return FPPackData(self.pspec)
23
24 def elaborate(self, platform):
25 m = Module()
26 comb = m.d.comb
27
28 z = FPNumBaseRecord(self.pspec.width, False, name="z")
29 m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
30 overflow_array = FPRoundingMode.make_array(
31 lambda rm: rm.overflow_rounds_to_inf(self.i.z.s))
32 overflow_rounds_to_inf = Signal()
33 m.d.comb += overflow_rounds_to_inf.eq(overflow_array[self.i.rm])
34
35 with m.If(~self.i.out_do_z):
36 with m.If(in_z.is_overflowed):
37 with m.If(overflow_rounds_to_inf):
38 comb += z.inf(self.i.z.s)
39 with m.Else():
40 comb += z.max_normal(self.i.z.s)
41 with m.Else():
42 comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
43 with m.Else():
44 comb += z.v.eq(self.i.oz)
45
46 comb += self.o.ctx.eq(self.i.ctx)
47 comb += self.o.z.eq(z.v)
48
49 return m