rename FPModBase* to PipeModBase*
[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 from nmigen.cli import main, verilog
7
8 from nmutil.pipemodbase import PipeModBase
9 from ieee754.fpcommon.fpbase import FPNumBaseRecord, FPNumBase
10 from ieee754.fpcommon.roundz import FPRoundData
11 from ieee754.fpcommon.getop import FPPipeContext
12
13
14 class FPPackData:
15
16 def __init__(self, pspec):
17 width = pspec.width
18 self.z = Signal(width, reset_less=True) # result
19 self.ctx = FPPipeContext(pspec)
20
21 # this is complicated: it's a workaround, due to the
22 # array-indexing not working properly in nmigen.
23 # self.ports() is used to access the ArrayProxy objects by name,
24 # however it doesn't work recursively. the workaround:
25 # drop the sub-objects into *this* scope and they can be
26 # accessed / set. it's horrible.
27 self.muxid = self.ctx.muxid
28 self.op = self.ctx.op
29
30 def eq(self, i):
31 return [self.z.eq(i.z), self.ctx.eq(i.ctx)]
32
33 def __iter__(self):
34 yield self.z
35 yield from self.ctx
36
37 def ports(self):
38 return list(self)
39
40
41 class FPPackMod(PipeModBase):
42
43 def __init__(self, pspec):
44 super().__init__(pspec, "pack")
45
46 def ispec(self):
47 return FPRoundData(self.pspec)
48
49 def ospec(self):
50 return FPPackData(self.pspec)
51
52 def elaborate(self, platform):
53 m = Module()
54 comb = m.d.comb
55
56 z = FPNumBaseRecord(self.pspec.width, False, name="z")
57 m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
58
59 with m.If(~self.i.out_do_z):
60 with m.If(in_z.is_overflowed):
61 comb += z.inf(self.i.z.s)
62 with m.Else():
63 comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
64 with m.Else():
65 comb += z.v.eq(self.i.oz)
66
67 comb += self.o.ctx.eq(self.i.ctx)
68 comb += self.o.z.eq(z.v)
69
70 return m