add operand down pipeline chain
[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, Elaboratable
6 from nmigen.cli import main, verilog
7
8 from ieee754.fpcommon.fpbase import FPNumOut, FPNumBaseRecord, FPNumBase
9 from ieee754.fpcommon.fpbase import FPState
10 from .roundz import FPRoundData
11 from nmutil.singlepipe import Object
12 from ieee754.fpcommon.getop import FPBaseData
13
14
15 class FPPackData(Object):
16
17 def __init__(self, width, id_wid, op_wid):
18 Object.__init__(self)
19 self.z = Signal(width, reset_less=True) # result
20 self.mid = Signal(id_wid, reset_less=True) # multiplex ID
21 self.op = Signal(op_wid or 0, reset_less=True) # operand width
22
23
24 class FPPackMod(Elaboratable):
25
26 def __init__(self, width, id_wid, op_wid=None):
27 self.width = width
28 self.id_wid = id_wid
29 self.op_wid = op_wid
30 self.i = self.ispec()
31 self.o = self.ospec()
32
33 def ispec(self):
34 return FPRoundData(self.width, self.id_wid, self.op_wid)
35
36 def ospec(self):
37 return FPPackData(self.width, self.id_wid, self.op_wid)
38
39 def process(self, i):
40 return self.o
41
42 def setup(self, m, in_z):
43 """ links module to inputs and outputs
44 """
45 m.submodules.pack = self
46 m.d.comb += self.i.eq(in_z)
47
48 def elaborate(self, platform):
49 m = Module()
50 z = FPNumBaseRecord(self.width, False)
51 m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
52 #m.submodules.pack_out_z = out_z = FPNumOut(z)
53 m.d.comb += self.o.mid.eq(self.i.mid)
54 if self.i.op_wid:
55 m.d.comb += self.o.op.eq(self.i.op)
56 with m.If(~self.i.out_do_z):
57 with m.If(in_z.is_overflowed):
58 m.d.comb += z.inf(self.i.z.s)
59 with m.Else():
60 m.d.comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
61 with m.Else():
62 m.d.comb += z.v.eq(self.i.oz)
63 m.d.comb += self.o.z.eq(z.v)
64 return m
65
66
67 class FPPack(FPState):
68
69 def __init__(self, width, id_wid):
70 FPState.__init__(self, "pack")
71 self.mod = FPPackMod(width)
72 self.out_z = self.ospec()
73
74 def ispec(self):
75 return self.mod.ispec()
76
77 def ospec(self):
78 return self.mod.ospec()
79
80 def setup(self, m, in_z):
81 """ links module to inputs and outputs
82 """
83 self.mod.setup(m, in_z)
84
85 m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
86 m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
87
88 def action(self, m):
89 m.next = "pack_put_z"