split out pack to separate module
[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, Cat, Mux, Array, Const
6 from nmigen.lib.coding import PriorityEncoder
7 from nmigen.cli import main, verilog
8 from math import log
9
10 from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPNumBase
11 from fpbase import MultiShiftRMerge, Trigger
12 from singlepipe import (ControlBase, StageChain, UnbufferedPipeline,
13 PassThroughStage)
14 from multipipe import CombMuxOutPipe
15 from multipipe import PriorityCombMuxInPipe
16
17 from fpbase import FPState, FPID
18 from fpcommon.roundz import FPRoundData
19
20
21 class FPPackData:
22
23 def __init__(self, width, id_wid):
24 self.z = Signal(width, reset_less=True)
25 self.mid = Signal(id_wid, reset_less=True)
26
27 def eq(self, i):
28 return [self.z.eq(i.z), self.mid.eq(i.mid)]
29
30 def ports(self):
31 return [self.z, self.mid]
32
33
34 class FPPackMod:
35
36 def __init__(self, width, id_wid):
37 self.width = width
38 self.id_wid = id_wid
39 self.i = self.ispec()
40 self.o = self.ospec()
41
42 def ispec(self):
43 return FPRoundData(self.width, self.id_wid)
44
45 def ospec(self):
46 return FPPackData(self.width, self.id_wid)
47
48 def process(self, i):
49 return self.o
50
51 def setup(self, m, in_z):
52 """ links module to inputs and outputs
53 """
54 m.submodules.pack = self
55 m.d.comb += self.i.eq(in_z)
56
57 def elaborate(self, platform):
58 m = Module()
59 z = FPNumOut(self.width, False)
60 m.submodules.pack_in_z = self.i.z
61 m.submodules.pack_out_z = z
62 m.d.comb += self.o.mid.eq(self.i.mid)
63 with m.If(~self.i.out_do_z):
64 with m.If(self.i.z.is_overflowed):
65 m.d.comb += z.inf(self.i.z.s)
66 with m.Else():
67 m.d.comb += z.create(self.i.z.s, self.i.z.e, self.i.z.m)
68 with m.Else():
69 m.d.comb += z.v.eq(self.i.oz)
70 m.d.comb += self.o.z.eq(z.v)
71 return m
72
73
74 class FPPack(FPState):
75
76 def __init__(self, width, id_wid):
77 FPState.__init__(self, "pack")
78 self.mod = FPPackMod(width)
79 self.out_z = self.ospec()
80
81 def ispec(self):
82 return self.mod.ispec()
83
84 def ospec(self):
85 return self.mod.ospec()
86
87 def setup(self, m, in_z):
88 """ links module to inputs and outputs
89 """
90 self.mod.setup(m, in_z)
91
92 m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
93 m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
94
95 def action(self, m):
96 m.next = "pack_put_z"