pass in flatten/processing function into _connect_in/out
[ieee754fpu.git] / src / add / 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 fpbase import FPNumOut
9 from fpbase import FPState
10 from fpcommon.roundz import FPRoundData
11
12
13 class FPPackData:
14
15 def __init__(self, width, id_wid):
16 self.z = Signal(width, reset_less=True)
17 self.mid = Signal(id_wid, reset_less=True)
18
19 def eq(self, i):
20 return [self.z.eq(i.z), self.mid.eq(i.mid)]
21
22 def ports(self):
23 return [self.z, self.mid]
24
25
26 class FPPackMod:
27
28 def __init__(self, width, id_wid):
29 self.width = width
30 self.id_wid = id_wid
31 self.i = self.ispec()
32 self.o = self.ospec()
33
34 def ispec(self):
35 return FPRoundData(self.width, self.id_wid)
36
37 def ospec(self):
38 return FPPackData(self.width, self.id_wid)
39
40 def process(self, i):
41 return self.o
42
43 def setup(self, m, in_z):
44 """ links module to inputs and outputs
45 """
46 m.submodules.pack = self
47 m.d.comb += self.i.eq(in_z)
48
49 def elaborate(self, platform):
50 m = Module()
51 z = FPNumOut(self.width, False)
52 m.submodules.pack_in_z = self.i.z
53 m.submodules.pack_out_z = z
54 m.d.comb += self.o.mid.eq(self.i.mid)
55 with m.If(~self.i.out_do_z):
56 with m.If(self.i.z.is_overflowed):
57 m.d.comb += z.inf(self.i.z.s)
58 with m.Else():
59 m.d.comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
60 with m.Else():
61 m.d.comb += z.v.eq(self.i.oz)
62 m.d.comb += self.o.z.eq(z.v)
63 return m
64
65
66 class FPPack(FPState):
67
68 def __init__(self, width, id_wid):
69 FPState.__init__(self, "pack")
70 self.mod = FPPackMod(width)
71 self.out_z = self.ospec()
72
73 def ispec(self):
74 return self.mod.ispec()
75
76 def ospec(self):
77 return self.mod.ospec()
78
79 def setup(self, m, in_z):
80 """ links module to inputs and outputs
81 """
82 self.mod.setup(m, in_z)
83
84 m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
85 m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
86
87 def action(self, m):
88 m.next = "pack_put_z"