add __iter__ to several classes, add global shape() function use in FIFOControl
[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 __iter__(self):
20 yield self.z
21 yield self.mid
22
23 def eq(self, i):
24 return [self.z.eq(i.z), self.mid.eq(i.mid)]
25
26 def ports(self):
27 return list(self)
28
29
30 class FPPackMod:
31
32 def __init__(self, width, id_wid):
33 self.width = width
34 self.id_wid = id_wid
35 self.i = self.ispec()
36 self.o = self.ospec()
37
38 def ispec(self):
39 return FPRoundData(self.width, self.id_wid)
40
41 def ospec(self):
42 return FPPackData(self.width, self.id_wid)
43
44 def process(self, i):
45 return self.o
46
47 def setup(self, m, in_z):
48 """ links module to inputs and outputs
49 """
50 m.submodules.pack = self
51 m.d.comb += self.i.eq(in_z)
52
53 def elaborate(self, platform):
54 m = Module()
55 z = FPNumOut(self.width, False)
56 m.submodules.pack_in_z = self.i.z
57 m.submodules.pack_out_z = z
58 m.d.comb += self.o.mid.eq(self.i.mid)
59 with m.If(~self.i.out_do_z):
60 with m.If(self.i.z.is_overflowed):
61 m.d.comb += z.inf(self.i.z.s)
62 with m.Else():
63 m.d.comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
64 with m.Else():
65 m.d.comb += z.v.eq(self.i.oz)
66 m.d.comb += self.o.z.eq(z.v)
67 return m
68
69
70 class FPPack(FPState):
71
72 def __init__(self, width, id_wid):
73 FPState.__init__(self, "pack")
74 self.mod = FPPackMod(width)
75 self.out_z = self.ospec()
76
77 def ispec(self):
78 return self.mod.ispec()
79
80 def ospec(self):
81 return self.mod.ospec()
82
83 def setup(self, m, in_z):
84 """ links module to inputs and outputs
85 """
86 self.mod.setup(m, in_z)
87
88 m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
89 m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
90
91 def action(self, m):
92 m.next = "pack_put_z"