add operand down pipeline chain
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 1 Jul 2019 16:28:23 +0000 (17:28 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 1 Jul 2019 16:28:23 +0000 (17:28 +0100)
15 files changed:
src/ieee754/fpadd/pipeline.py
src/ieee754/fpadd/specialcases.py
src/ieee754/fpcommon/corrections.py
src/ieee754/fpcommon/denorm.py
src/ieee754/fpcommon/getop.py
src/ieee754/fpcommon/normtopack.py
src/ieee754/fpcommon/pack.py
src/ieee754/fpcommon/postcalc.py
src/ieee754/fpcommon/postnormalise.py
src/ieee754/fpcommon/roundz.py
src/ieee754/fpmul/mul0.py
src/ieee754/fpmul/mul1.py
src/ieee754/fpmul/mulstages.py
src/ieee754/fpmul/pipeline.py
src/ieee754/fpmul/specialcases.py

index 7b37a6877d797ee2b0a0d4f03556ec3c151e4981..1458dfefc0a391c5feb62f6d04a87534790e4048 100644 (file)
@@ -46,14 +46,15 @@ class FPADDMuxInOut(ReservationStations):
 
         Fan-in and Fan-out are combinatorial.
     """
-    def __init__(self, width, num_rows):
+    def __init__(self, width, num_rows, op_wid=None):
         self.width = width
         self.id_wid = num_bits(width)
+        self.op_wid = op_wid
         self.alu = FPADDBasePipe(width, self.id_wid)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.id_wid)
+        return FPPackData(self.width, self.id_wid, self.op_wid)
index 4e1a765b110bd115f82d044a4a37c74ad2f19fe2..2266221a3e312f769ca42543c3313ed80fffadb1 100644 (file)
@@ -20,17 +20,18 @@ class FPAddSpecialCasesMod(Elaboratable):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid)
+        return FPSCData(self.width, self.id_wid, True, self.op_wid)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -145,6 +146,8 @@ class FPAddSpecialCasesMod(Elaboratable):
 
         m.d.comb += self.o.oz.eq(self.o.z.v)
         m.d.comb += self.o.mid.eq(self.i.mid)
+        if self.o.op_wid:
+            m.d.comb += self.o.op.eq(self.i.op)
 
         return m
 
@@ -182,18 +185,19 @@ class FPAddSpecialCasesDeNorm(FPState, SimpleHandshake):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         FPState.__init__(self, "special_cases")
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         SimpleHandshake.__init__(self, self) # pipe is its own stage
         self.out = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid) # SpecialCases ispec
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid) # SC ispec
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid) # DeNorm ospec
+        return FPSCData(self.width, self.id_wid, True, self.op_wid) # DeNorm
 
     def setup(self, m, i):
         """ links module to inputs and outputs
index 5869d7e0cc9ee644c1c4906686c2be83e468fd9f..09236194757ce4d8bfd9b642f0747977962d2f42 100644 (file)
@@ -10,17 +10,18 @@ from .roundz import FPRoundData
 
 class FPCorrectionsMod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid # operand width
         self.i = self.ispec()
         self.out_z = self.ospec()
 
     def ispec(self):
-        return FPRoundData(self.width, self.id_wid)
+        return FPRoundData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPRoundData(self.width, self.id_wid)
+        return FPRoundData(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.out_z
index 559c5ae244cc74191e3e7676dad6463e397ba7b0..cea8e2b78e8f8796a3699d224d915e92ee71aa86 100644 (file)
@@ -12,7 +12,7 @@ from ieee754.fpcommon.fpbase import FPState, FPNumBase
 
 class FPSCData:
 
-    def __init__(self, width, id_wid, m_extra=True):
+    def __init__(self, width, id_wid, m_extra=True, op_wid=None):
 
         # NOTE: difference between z and oz is that oz is created by
         # special-cases module(s) and will propagate, along with its
@@ -24,6 +24,10 @@ class FPSCData:
         self.oz = Signal(width, reset_less=True)   # "finished" (bypass) result
         self.out_do_z = Signal(reset_less=True)    # "bypass" enabled
         self.mid = Signal(id_wid, reset_less=True) # multiplexer ID
+        self.op_wid = op_wid
+        if op_wid:
+            self.op = Signal(op_wid, reset_less=True) # operand
+
 
     def __iter__(self):
         yield from self.a
@@ -32,26 +36,32 @@ class FPSCData:
         yield self.oz
         yield self.out_do_z
         yield self.mid
+        if op_wid:
+            yield self.op
 
     def eq(self, i):
-        return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+        ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
                 self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
+        if self.op_wid:
+            ret.append(self.op.eq(i.op))
+        return ret
 
 
 class FPAddDeNormMod(FPState, Elaboratable):
 
-    def __init__(self, width, id_wid, m_extra=True):
+    def __init__(self, width, id_wid, m_extra=True, op_wid=None):
         self.width = width
         self.id_wid = id_wid
         self.m_extra = m_extra
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, self.m_extra)
+        return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, self.m_extra)
+        return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid)
 
     def process(self, i):
         return self.o
index 38eb937771259597679324ec8855efd73df382c8..36352ace0a63f5ec4015f4af7c067a537bf090a0 100644 (file)
@@ -82,24 +82,49 @@ class FPNumBase2Ops:
         return [self.a, self.b, self.mid]
 
 
-class FPADDBaseData:
+class FPBaseData:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, n_ops, width, id_wid, op_wid):
         self.width = width
         self.id_wid = id_wid
-        self.a  = Signal(width)                      # operand a
-        self.b  = Signal(width)                      # operand b
+        self.op_wid = op_wid
+        ops = []
+        for i in range(n_ops):
+            name = chr(ord("a")+i)
+            operand = Signal(width, name=name)
+            setattr(self, name, operand)
+            ops.append(operand)
+        self.ops = ops
         self.mid = Signal(id_wid, reset_less=True)   # RS multiplex ID
+        self.op = Signal(op_wid, reset_less=True)
 
     def eq(self, i):
-        return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
+        ret = []
+        for op1, op2 in zip(self.ops, i.ops):
+            ret.append(op1.eq(op2))
+        ret.append(self.mid.eq(i.mid))
+        if self.op_wid:
+            ret.append(self.op.eq(i.op))
+        return ret
+
+    def __iter__(self):
+        if self.ops:
+            yield from self.ops
+        yield self.mid
+        if self.id_wid:
+            yield self.op
 
     def ports(self):
-        return [self.a, self.b, self.mid]
+        return list(self)
+
+class FPADDBaseData(FPBaseData):
+
+    def __init__(self, width, id_wid, op_wid):
+        FPBaseData.__init__(self, 2, width, id_wid, op_wid)
 
 
 class FPGet2OpMod(PrevControl):
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         PrevControl.__init__(self)
         self.width = width
         self.id_wid = id_wid
@@ -108,10 +133,10 @@ class FPGet2OpMod(PrevControl):
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.o
@@ -129,10 +154,10 @@ class FPGet2Op(FPState):
     """ gets operands
     """
 
-    def __init__(self, in_state, out_state, width, id_wid):
+    def __init__(self, in_state, out_state, width, id_wid, op_wid=None):
         FPState.__init__(self, in_state)
         self.out_state = out_state
-        self.mod = FPGet2OpMod(width, id_wid)
+        self.mod = FPGet2OpMod(width, id_wid, op_wid)
         self.o = self.ospec()
         self.in_stb = Signal(reset_less=True)
         self.out_ack = Signal(reset_less=True)
index 9cba72550d9366018fcb1cb0e08c9afc91c77162..49f7c76e497524e4b3b41ca8d6e1f1dac7e09727 100644 (file)
@@ -16,17 +16,18 @@ from .pack import FPPackData, FPPackMod
 
 class FPNormToPack(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         FPState.__init__(self, "normalise_1")
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.width = width
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
 
     def ispec(self):
-        return FPAddStage1Data(self.width, self.id_wid) # Norm1ModSingle ispec
+        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPPackData(self.width, self.id_wid) # FPPackMod ospec
+        return FPPackData(self.width, self.id_wid, self.op_wid) # FPPackMod
 
     def setup(self, m, i):
         """ links module to inputs and outputs
index 9a9e4d5c749738af4ae765e295c83ff7736cbba7..e03edd4fcbfb612441f9bb864f941f2ce8e52e21 100644 (file)
@@ -9,29 +9,32 @@ from ieee754.fpcommon.fpbase import FPNumOut, FPNumBaseRecord, FPNumBase
 from ieee754.fpcommon.fpbase import FPState
 from .roundz import FPRoundData
 from nmutil.singlepipe import Object
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPPackData(Object):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid):
         Object.__init__(self)
         self.z = Signal(width, reset_less=True)    # result
         self.mid = Signal(id_wid, reset_less=True) # multiplex ID
+        self.op = Signal(op_wid or 0, reset_less=True) # operand width
 
 
 class FPPackMod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPRoundData(self.width, self.id_wid)
+        return FPRoundData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPPackData(self.width, self.id_wid)
+        return FPPackData(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.o
@@ -48,6 +51,8 @@ class FPPackMod(Elaboratable):
         m.submodules.pack_in_z = in_z = FPNumBase(self.i.z)
         #m.submodules.pack_out_z = out_z = FPNumOut(z)
         m.d.comb += self.o.mid.eq(self.i.mid)
+        if self.i.op_wid:
+            m.d.comb += self.o.op.eq(self.i.op)
         with m.If(~self.i.out_do_z):
             with m.If(in_z.is_overflowed):
                 m.d.comb += z.inf(self.i.z.s)
index 61e2f5288273db4b46f113e9d9e9d058d41503d8..ddb7fb3d83c7acf70b60198503f0a8b3de22a82a 100644 (file)
@@ -4,23 +4,26 @@
 
 from nmigen import Signal
 from ieee754.fpcommon.fpbase import Overflow, FPNumBaseRecord
+from ieee754.fpcommon.getop import FPBaseData
 
-class FPAddStage1Data:
+class FPAddStage1Data(FPBaseData):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
+        FPBaseData.__init__(self, 0, width, id_wid, op_wid)
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         self.of = Overflow()
-        self.mid = Signal(id_wid, reset_less=True)
 
     def __iter__(self):
         yield from self.z
         yield self.out_do_z
         yield self.oz
         yield from self.of
-        yield self.mid
+        yield from FPBaseData.__iter__(self)
 
     def eq(self, i):
-        return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
-                self.of.eq(i.of), self.mid.eq(i.mid)]
+        ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+              self.of.eq(i.of),] + FPBaseData.eq(self, i)
+
+        return ret
index 1d9ee94f04d1b7b3e4d35f94cd7819c3208fc4b2..c083bc075502db8110d7dfda009fb2fa98da2f29 100644 (file)
@@ -15,31 +15,38 @@ from .postcalc import FPAddStage1Data
 
 class FPNorm1Data:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.roundz = Signal(reset_less=True, name="norm1_roundz")
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         self.mid = Signal(id_wid, reset_less=True)
+        self.op_wid = op_wid
+        if op_wid:
+            self.op = Signal(op_wid, reset_less=True) # operand
 
     def eq(self, i):
-        return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+        ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
                 self.roundz.eq(i.roundz), self.mid.eq(i.mid)]
+        if self.op_wid:
+            ret.append(self.op.eq(i.op))
+        return ret
 
 
 class FPNorm1ModSingle(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPAddStage1Data(self.width, self.id_wid)
+        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPNorm1Data(self.width, self.id_wid)
+        return FPNorm1Data(self.width, self.id_wid, self.op_wid)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
index 36253d3753b98ba2d07f2d83bce374aad77edbcd..dd65551022f307af249a06de9d9090cdccb30ede 100644 (file)
@@ -12,31 +12,39 @@ from .postnormalise import FPNorm1Data
 
 class FPRoundData:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.z = FPNumBaseRecord(width, False)
         self.mid = Signal(id_wid, reset_less=True) # multiplex ID
         # pipeline bypass [data comes from specialcases]
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
+        self.op_wid = op_wid
+        if op_wid:
+            self.op = Signal(op_wid, reset_less=True)
 
     def eq(self, i):
-        return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+        ret = [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
                 self.mid.eq(i.mid)]
+        if self.op_wid:
+            ret.append(self.op.eq(i.op))
+        return ret
+
 
 
 class FPRoundMod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.out_z = self.ospec()
 
     def ispec(self):
-        return FPNorm1Data(self.width, self.id_wid)
+        return FPNorm1Data(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPRoundData(self.width, self.id_wid)
+        return FPRoundData(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.out_z
index 6c264fbcc7895733536c6e68d2814b742891339d..ea0753daa707c42b493e725205f49656ba48ef52 100644 (file)
@@ -8,36 +8,38 @@ from nmigen.cli import main, verilog
 from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPMulStage0Data:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
+        FPBaseData.__init__(self, 0, width, id_wid, op_wid)
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
         self.product = Signal(mw, reset_less=True)
-        self.mid = Signal(id_wid, reset_less=True)
 
     def eq(self, i):
         return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
-                self.product.eq(i.product), self.mid.eq(i.mid)]
+                self.product.eq(i.product)] + FPBaseData.eq(self, i)
 
 
 class FPMulStage0Mod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, False)
+        return FPSCData(self.width, self.id_wid, False, self.op_wid)
 
     def ospec(self):
-        return FPMulStage0Data(self.width, self.id_wid)
+        return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.o
@@ -71,6 +73,8 @@ class FPMulStage0Mod(Elaboratable):
         m.d.comb += self.o.oz.eq(self.i.oz)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.mid.eq(self.i.mid)
+        if self.o.op_wid:
+            m.d.comb += self.o.op.eq(self.i.op)
         return m
 
 
index d932871bbeaee3c4cac98c6750cc40824676bb58..0c5cb6e5ffdb7d85ede8e41071cf4e3690ef4bd8 100644 (file)
@@ -12,17 +12,18 @@ class FPMulStage1Mod(FPState, Elaboratable):
     """ Second stage of mul: preparation for normalisation.
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPMulStage0Data(self.width, self.id_wid)
+        return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid)
+        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
 
     def process(self, i):
         return self.o
@@ -51,6 +52,8 @@ class FPMulStage1Mod(FPState, Elaboratable):
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.oz.eq(self.i.oz)
         m.d.comb += self.o.mid.eq(self.i.mid)
+        if self.o.op_wid:
+            m.d.comb += self.o.op.eq(self.i.op)
 
         return m
 
index e07b05aab1fe0c025688c05b397891d43cafa682..5b6be6ec8dd1fefd059c5bae748f2b05d5cd159f 100644 (file)
@@ -14,26 +14,27 @@ from .mul1 import FPMulStage1Mod
 
 class FPMulStages(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         FPState.__init__(self, "align")
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
         self.m1o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, False)
+        return FPSCData(self.width, self.id_wid, False, self.op_wid)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
+        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
 
         # chain MulStage0 and MulStage1
-        m0mod = FPMulStage0Mod(self.width, self.id_wid)
-        m1mod = FPMulStage1Mod(self.width, self.id_wid)
+        m0mod = FPMulStage0Mod(self.width, self.id_wid, self.op_wid)
+        m1mod = FPMulStage1Mod(self.width, self.id_wid, self.op_wid)
 
         chain = StageChain([m0mod, m1mod])
         chain.setup(m, i)
index 0473660010ad1afafef85d3c2040021451c47e3d..a13ec4ced369b7f20322a8a884e75ca413b74785 100644 (file)
@@ -44,14 +44,15 @@ class FPMULMuxInOut(ReservationStations):
 
         Fan-in and Fan-out are combinatorial.
     """
-    def __init__(self, width, num_rows):
+    def __init__(self, width, num_rows, op_wid=0):
         self.width = width
         self.id_wid = num_bits(width)
+        self.op_wid = op_wid
         self.alu = FPMULBasePipe(width, self.id_wid)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.id_wid)
+        return FPPackData(self.width, self.id_wid, self.op_wid)
index 0149bb3ba8be6aab26b5970a900b76f49f5a3ebd..18f93dd23c8406dcd1b22feb2a033227cd6dfe1c 100644 (file)
@@ -18,17 +18,18 @@ class FPMulSpecialCasesMod(Elaboratable):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False)
+        return FPSCData(self.width, self.id_wid, False, self.op_wid)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -131,18 +132,19 @@ class FPMulSpecialCasesDeNorm(FPState, SimpleHandshake):
     """ special cases: NaNs, infs, zeros, denormalised
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, op_wid=None):
         FPState.__init__(self, "special_cases")
         self.width = width
         self.id_wid = id_wid
+        self.op_wid = op_wid
         SimpleHandshake.__init__(self, self) # pipe is its own stage
         self.out = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid) # SpecialCases ispec
+        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False) # DeNorm ospec
+        return FPSCData(self.width, self.id_wid, False, self.op_wid)
 
     def setup(self, m, i):
         """ links module to inputs and outputs