use new FPBaseData as a "spec" (context), initialised with a dict (pspec)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 2 Jul 2019 08:34:25 +0000 (09:34 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 2 Jul 2019 08:34:25 +0000 (09:34 +0100)
21 files changed:
src/ieee754/fpadd/add0.py
src/ieee754/fpadd/add1.py
src/ieee754/fpadd/addstages.py
src/ieee754/fpadd/align.py
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
src/nmutil/multipipe.py
src/nmutil/nmoperator.py

index a76374c4217b6049d2412f8bdb812217bc2ed6b1..b487b0dd167467271421a787cb8395dff6311384 100644 (file)
@@ -8,35 +8,37 @@ from nmigen.cli import main, verilog
 from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPAddStage0Data:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         self.tot = Signal(self.z.m_width + 4, reset_less=True)
-        self.mid = Signal(id_wid, reset_less=True)
+        self.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
     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.tot.eq(i.tot), self.mid.eq(i.mid)]
+                self.tot.eq(i.tot), self.ctx.eq(i.ctx)]
 
 
 class FPAddStage0Mod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid)
+        return FPSCData(self.width, self.pspec, True)
 
     def ospec(self):
-        return FPAddStage0Data(self.width, self.id_wid)
+        return FPAddStage0Data(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -86,7 +88,7 @@ class FPAddStage0Mod(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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         return m
 
 
@@ -96,7 +98,7 @@ class FPAddStage0(FPState):
         give greatest accuracy.
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "add_0")
         self.mod = FPAddStage0Mod(width)
         self.o = self.mod.ospec()
index 408b607577d936f55cc145571ebd5c1c86d5f343..e434be21fc9cb493e3119d384c36957ea74b02bb 100644 (file)
@@ -16,17 +16,17 @@ class FPAddStage1Mod(FPState, Elaboratable):
         detects when tot sum is too big (tot[27] is kinda a carry bit)
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPAddStage0Data(self.width, self.id_wid)
+        return FPAddStage0Data(self.width, self.pspec)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid)
+        return FPAddStage1Data(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -65,14 +65,14 @@ class FPAddStage1Mod(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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
 
 class FPAddStage1(FPState):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "add_1")
         self.mod = FPAddStage1Mod(width)
         self.out_z = FPNumBase(width, False)
index b398a2742072246d3f0dc523804c5b09517fc556..45688c1c308a18b1972812d9869825a9688f4ab7 100644 (file)
@@ -18,27 +18,27 @@ from .add1 import FPAddStage1Mod
 
 class FPAddAlignSingleAdd(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "align")
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
         self.a1o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid)
+        return FPSCData(self.width, self.pspec, True)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
+        return FPAddStage1Data(self.width, self.pspec) # AddStage1 ospec
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
 
         # chain AddAlignSingle, AddStage0 and AddStage1
-        mod = FPAddAlignSingleMod(self.width, self.id_wid)
-        a0mod = FPAddStage0Mod(self.width, self.id_wid)
-        a1mod = FPAddStage1Mod(self.width, self.id_wid)
+        mod = FPAddAlignSingleMod(self.width, self.pspec)
+        a0mod = FPAddStage0Mod(self.width, self.pspec)
+        a1mod = FPAddStage1Mod(self.width, self.pspec)
 
         chain = StageChain([mod, a0mod, a1mod])
         chain.setup(m, i)
index 62dcc379627ee80164e5d581d7e13783f732f72d..171365ef476a60bf1bd41fb163215e08ee5c6b56 100644 (file)
@@ -10,21 +10,23 @@ from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.fpbase import MultiShiftRMerge
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPNumIn2Ops:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.a = FPNumBaseRecord(width)
         self.b = FPNumBaseRecord(width)
         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.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
     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.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
+                self.a.eq(i.a), self.b.eq(i.b), self.ctx.eq(i.ctx)]
 
 
 
@@ -72,9 +74,9 @@ class FPAddAlignMultiMod(FPState):
 
 class FPAddAlignMulti(FPState):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "align")
-        self.mod = FPAddAlignMultiMod(width)
+        self.mod = FPAddAlignMultiMod(width, pspec)
         self.out_a = FPNumBaseRecord(width)
         self.out_b = FPNumBaseRecord(width)
         self.exp_eq = Signal(reset_less=True)
@@ -96,17 +98,17 @@ class FPAddAlignMulti(FPState):
 
 class FPAddAlignSingleMod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid)
+        return FPSCData(self.width, self.pspec, True)
 
     def ospec(self):
-        return FPNumIn2Ops(self.width, self.id_wid)
+        return FPNumIn2Ops(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -181,7 +183,7 @@ class FPAddAlignSingleMod(Elaboratable):
                              self.o.a.s.eq(self.i.a.s), # whoops forgot sign
                             ]
 
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         m.d.comb += self.o.z.eq(self.i.z)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.oz.eq(self.i.oz)
@@ -191,9 +193,9 @@ class FPAddAlignSingleMod(Elaboratable):
 
 class FPAddAlignSingle(FPState):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "align")
-        self.mod = FPAddAlignSingleMod(width, id_wid)
+        self.mod = FPAddAlignSingleMod(width, pspec)
         self.out_a = FPNumIn(None, width)
         self.out_b = FPNumIn(None, width)
 
index 1458dfefc0a391c5feb62f6d04a87534790e4048..7dbd254d1f9b61f7c19fd0ffd9e2a90b9bf41fe6 100644 (file)
@@ -50,11 +50,12 @@ class FPADDMuxInOut(ReservationStations):
         self.width = width
         self.id_wid = num_bits(width)
         self.op_wid = op_wid
-        self.alu = FPADDBasePipe(width, self.id_wid)
+        self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
+        self.alu = FPADDBasePipe(width, self.pspec)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.id_wid, self.op_wid)
+        return FPPackData(self.width, self.pspec)
index 2266221a3e312f769ca42543c3313ed80fffadb1..c0c8e24d3f0c89e1325665699a3ec0c16119988c 100644 (file)
@@ -20,18 +20,17 @@ class FPAddSpecialCasesMod(Elaboratable):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, True, self.op_wid)
+        return FPSCData(self.width, self.pspec, True)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -145,9 +144,7 @@ class FPAddSpecialCasesMod(Elaboratable):
             m.d.comb += self.o.out_do_z.eq(0)
 
         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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
@@ -169,7 +166,7 @@ class FPAddSpecialCases(FPState):
         """
         self.mod.setup(m, i, self.out_do_z)
         m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
-        m.d.sync += self.out_z.mid.eq(self.mod.o.mid)  # (and mid)
+        m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)  # (and mid)
 
     def action(self, m):
         self.idsync(m)
@@ -185,25 +182,24 @@ class FPAddSpecialCasesDeNorm(FPState, SimpleHandshake):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "special_cases")
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         SimpleHandshake.__init__(self, self) # pipe is its own stage
         self.out = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid) # SC ispec
+        return FPADDBaseData(self.width, self.pspec) # SC ispec
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, True, self.op_wid) # DeNorm
+        return FPSCData(self.width, self.pspec, True) # DeNorm
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
-        smod = FPAddSpecialCasesMod(self.width, self.id_wid)
-        dmod = FPAddDeNormMod(self.width, self.id_wid)
+        smod = FPAddSpecialCasesMod(self.width, self.pspec)
+        dmod = FPAddDeNormMod(self.width, self.pspec, True)
 
         chain = StageChain([smod, dmod])
         chain.setup(m, i)
index 09236194757ce4d8bfd9b642f0747977962d2f42..500792265936af1dfab7bb390f173077fbbaf06e 100644 (file)
@@ -10,18 +10,17 @@ from .roundz import FPRoundData
 
 class FPCorrectionsMod(Elaboratable):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid # operand width
+        self.pspec = pspec
         self.i = self.ispec()
         self.out_z = self.ospec()
 
     def ispec(self):
-        return FPRoundData(self.width, self.id_wid, self.op_wid)
+        return FPRoundData(self.width, self.pspec)
 
     def ospec(self):
-        return FPRoundData(self.width, self.id_wid, self.op_wid)
+        return FPRoundData(self.width, self.pspec)
 
     def process(self, i):
         return self.out_z
@@ -62,7 +61,7 @@ class FPCorrections(FPState):
         self.mod.setup(m, in_z)
 
         m.d.sync += self.out_z.eq(self.mod.out_z)
-        m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+        m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
 
     def action(self, m):
         m.next = "pack"
index cea8e2b78e8f8796a3699d224d915e92ee71aa86..f6b26c2ad76c7231ae0acc177cbaf5659d07697a 100644 (file)
@@ -8,11 +8,12 @@ from math import log
 
 from ieee754.fpcommon.fpbase import FPNumIn, FPNumOut, FPNumBaseRecord
 from ieee754.fpcommon.fpbase import FPState, FPNumBase
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPSCData:
 
-    def __init__(self, width, id_wid, m_extra=True, op_wid=None):
+    def __init__(self, width, pspec, m_extra):
 
         # NOTE: difference between z and oz is that oz is created by
         # special-cases module(s) and will propagate, along with its
@@ -23,11 +24,8 @@ class FPSCData:
         self.z = FPNumBaseRecord(width, False)     # denormed result 
         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
-
+        self.ctx = FPBaseData(width, pspec) 
+        self.mid = self.ctx.mid
 
     def __iter__(self):
         yield from self.a
@@ -35,33 +33,28 @@ class FPSCData:
         yield from self.z
         yield self.oz
         yield self.out_do_z
-        yield self.mid
-        if op_wid:
-            yield self.op
+        yield from self.ctx
 
     def eq(self, i):
         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))
+                self.a.eq(i.a), self.b.eq(i.b), self.ctx.eq(i.ctx)]
         return ret
 
 
 class FPAddDeNormMod(FPState, Elaboratable):
 
-    def __init__(self, width, id_wid, m_extra=True, op_wid=None):
+    def __init__(self, width, pspec, m_extra):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         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, self.op_wid)
+        return FPSCData(self.width, self.pspec, self.m_extra)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, self.m_extra, self.op_wid)
+        return FPSCData(self.width, self.pspec, self.m_extra)
 
     def process(self, i):
         return self.o
@@ -94,7 +87,7 @@ class FPAddDeNormMod(FPState, Elaboratable):
             with m.Else():
                 m.d.comb += self.o.b.m[-1].eq(1) # set top mantissa bit
 
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         m.d.comb += self.o.z.eq(self.i.z)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.oz.eq(self.i.oz)
index 36352ace0a63f5ec4015f4af7c067a537bf090a0..17a8334bd13ba1998822a7d0c32f7f58849f01fe 100644 (file)
@@ -84,44 +84,58 @@ class FPNumBase2Ops:
 
 class FPBaseData:
 
-    def __init__(self, n_ops, width, id_wid, op_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        print (pspec)
+        self.id_wid = pspec['id_wid']
+        self.op_wid = pspec.get('op_wid', 0)
+        self.mid = Signal(self.id_wid, reset_less=True)   # RS multiplex ID
+        self.op = Signal(self.op_wid, reset_less=True)
+
+    def eq(self, i):
+        ret = [self.mid.eq(i.mid)]
+        if self.op_wid:
+            ret.append(self.op.eq(i.op))
+        return ret
+
+    def __iter__(self):
+        yield self.mid
+        if self.op_wid:
+            yield self.op
+
+    def ports(self):
+        return list(self)
+
+
+class FPADDBaseData:
+
+    def __init__(self, width, pspec, n_ops=2):
+        self.width = width
+        self.ctx = FPBaseData(width, pspec)
         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.mid = self.ctx.mid # make muxid available here: complicated
         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):
         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))
+        ret.append(self.ctx.eq(i.ctx))
         return ret
 
     def __iter__(self):
         if self.ops:
             yield from self.ops
-        yield self.mid
-        if self.id_wid:
-            yield self.op
+        yield from self.ctx
 
     def ports(self):
         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, op_wid=None):
index 49f7c76e497524e4b3b41ca8d6e1f1dac7e09727..0f05795a9a75b0ee7a04c3cc750034d41a3a3781 100644 (file)
@@ -16,28 +16,27 @@ from .pack import FPPackData, FPPackMod
 
 class FPNormToPack(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "normalise_1")
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.width = width
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
 
     def ispec(self):
-        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+        return FPAddStage1Data(self.width, self.pspec)
 
     def ospec(self):
-        return FPPackData(self.width, self.id_wid, self.op_wid) # FPPackMod
+        return FPPackData(self.width, self.pspec) # FPPackMod
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
 
         # Normalisation, Rounding Corrections, Pack - in a chain
-        nmod = FPNorm1ModSingle(self.width, self.id_wid)
-        rmod = FPRoundMod(self.width, self.id_wid)
-        cmod = FPCorrectionsMod(self.width, self.id_wid)
-        pmod = FPPackMod(self.width, self.id_wid)
+        nmod = FPNorm1ModSingle(self.width, self.pspec)
+        rmod = FPRoundMod(self.width, self.pspec)
+        cmod = FPCorrectionsMod(self.width, self.pspec)
+        pmod = FPPackMod(self.width, self.pspec)
         stages = [nmod, rmod, cmod, pmod]
         chain = StageChain(stages)
         chain.setup(m, i)
index e03edd4fcbfb612441f9bb864f941f2ce8e52e21..5df5ea7cb4db309b0c91465f027158c6f78598c3 100644 (file)
@@ -14,27 +14,25 @@ from ieee754.fpcommon.getop import FPBaseData
 
 class FPPackData(Object):
 
-    def __init__(self, width, id_wid, op_wid):
+    def __init__(self, width, pspec):
         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
-
+        self.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
 class FPPackMod(Elaboratable):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPRoundData(self.width, self.id_wid, self.op_wid)
+        return FPRoundData(self.width, self.pspec)
 
     def ospec(self):
-        return FPPackData(self.width, self.id_wid, self.op_wid)
+        return FPPackData(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -50,9 +48,7 @@ class FPPackMod(Elaboratable):
         z = FPNumBaseRecord(self.width, False)
         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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         with m.If(~self.i.out_do_z):
             with m.If(in_z.is_overflowed):
                 m.d.comb += z.inf(self.i.z.s)
@@ -83,7 +79,7 @@ class FPPack(FPState):
         self.mod.setup(m, in_z)
 
         m.d.sync += self.out_z.v.eq(self.mod.out_z.v)
-        m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+        m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
 
     def action(self, m):
         m.next = "pack_put_z"
index ddb7fb3d83c7acf70b60198503f0a8b3de22a82a..b815f8cfe0b300ff9ee18988ddd2300839ee9459 100644 (file)
@@ -6,24 +6,23 @@ from nmigen import Signal
 from ieee754.fpcommon.fpbase import Overflow, FPNumBaseRecord
 from ieee754.fpcommon.getop import FPBaseData
 
-class FPAddStage1Data(FPBaseData):
+class FPAddStage1Data:
 
-    def __init__(self, width, id_wid, op_wid=None):
-        FPBaseData.__init__(self, 0, width, id_wid, op_wid)
+    def __init__(self, width, pspec):
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         self.of = Overflow()
+        self.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
     def __iter__(self):
         yield from self.z
         yield self.out_do_z
         yield self.oz
         yield from self.of
-        yield from FPBaseData.__iter__(self)
+        yield from self.ctx
 
     def eq(self, i):
-        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
+        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.ctx.eq(i.ctx)]
index c083bc075502db8110d7dfda009fb2fa98da2f29..0f59386521c191afb53e560f51a611ff193cc962 100644 (file)
@@ -10,43 +10,39 @@ from math import log
 from ieee754.fpcommon.fpbase import Overflow, FPNumBase, FPNumBaseRecord
 from ieee754.fpcommon.fpbase import MultiShiftRMerge
 from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.getop import FPBaseData
 from .postcalc import FPAddStage1Data
 
 
 class FPNorm1Data:
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         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
+        self.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
     def eq(self, i):
         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))
+                self.roundz.eq(i.roundz), self.ctx.eq(i.ctx)]
         return ret
 
 
 class FPNorm1ModSingle(Elaboratable):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+        return FPAddStage1Data(self.width, self.pspec)
 
     def ospec(self):
-        return FPNorm1Data(self.width, self.id_wid, self.op_wid)
+        return FPNorm1Data(self.width, self.pspec)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -135,7 +131,7 @@ class FPNorm1ModSingle(Elaboratable):
                     self.o.z.e.eq(insel_z.e + ediff_n126),
                 ]
 
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.oz.eq(self.i.oz)
 
index dd65551022f307af249a06de9d9090cdccb30ede..a0b568689433b54b90adfc3d8d9ceb7effbb37bd 100644 (file)
@@ -7,44 +7,39 @@ from nmigen.cli import main, verilog
 
 from ieee754.fpcommon.fpbase import FPNumBase, FPNumBaseRecord
 from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.getop import FPBaseData
 from .postnormalise import FPNorm1Data
 
 
 class FPRoundData:
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.z = FPNumBaseRecord(width, False)
-        self.mid = Signal(id_wid, reset_less=True) # multiplex ID
+        self.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
         # 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):
         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))
+                self.ctx.eq(i.ctx)]
         return ret
 
 
-
 class FPRoundMod(Elaboratable):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.out_z = self.ospec()
 
     def ispec(self):
-        return FPNorm1Data(self.width, self.id_wid, self.op_wid)
+        return FPNorm1Data(self.width, self.pspec)
 
     def ospec(self):
-        return FPRoundData(self.width, self.id_wid, self.op_wid)
+        return FPRoundData(self.width, self.pspec)
 
     def process(self, i):
         return self.out_z
@@ -85,7 +80,7 @@ class FPRound(FPState):
 
         self.idsync(m)
         m.d.sync += self.out_z.eq(self.mod.out_z)
-        m.d.sync += self.out_z.mid.eq(self.mod.o.mid)
+        m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)
 
     def action(self, m):
         m.next = "corrections"
index ea0753daa707c42b493e725205f49656ba48ef52..5906785641cebe87a5a3771c84b89719bab62288 100644 (file)
@@ -13,33 +13,33 @@ from ieee754.fpcommon.getop import FPBaseData
 
 class FPMulStage0Data:
 
-    def __init__(self, width, id_wid, op_wid=None):
-        FPBaseData.__init__(self, 0, width, id_wid, op_wid)
+    def __init__(self, width, pspec):
         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.ctx = FPBaseData(width, pspec)
+        self.mid = self.ctx.mid
 
     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)] + FPBaseData.eq(self, i)
+                self.product.eq(i.product), self.ctx.eq(i.ctx)]
 
 
 class FPMulStage0Mod(Elaboratable):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, False, self.op_wid)
+        return FPSCData(self.width, self.pspec, False)
 
     def ospec(self):
-        return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
+        return FPMulStage0Data(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -72,9 +72,7 @@ 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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         return m
 
 
index 0c5cb6e5ffdb7d85ede8e41071cf4e3690ef4bd8..e6e58fc4da477873ee2a52cb6726ef8b5382fda0 100644 (file)
@@ -12,18 +12,17 @@ class FPMulStage1Mod(FPState, Elaboratable):
     """ Second stage of mul: preparation for normalisation.
     """
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPMulStage0Data(self.width, self.id_wid, self.op_wid)
+        return FPMulStage0Data(self.width, self.pspec)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+        return FPAddStage1Data(self.width, self.pspec)
 
     def process(self, i):
         return self.o
@@ -51,18 +50,16 @@ 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)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
 
 class FPMulStage1(FPState):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "multiply_1")
-        self.mod = FPMulStage1Mod(width)
+        self.mod = FPMulStage1Mod(width, pspec)
         self.out_z = FPNumBaseRecord(width, False)
         self.out_of = Overflow()
         self.norm_stb = Signal()
index 5b6be6ec8dd1fefd059c5bae748f2b05d5cd159f..53f4cc7f56ef8f508c6c286f9ff943af7545dd4c 100644 (file)
@@ -14,27 +14,26 @@ from .mul1 import FPMulStage1Mod
 
 class FPMulStages(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "align")
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
         self.m1o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, False, self.op_wid)
+        return FPSCData(self.width, self.pspec, False)
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid, self.op_wid)
+        return FPAddStage1Data(self.width, self.pspec)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
 
         # chain MulStage0 and MulStage1
-        m0mod = FPMulStage0Mod(self.width, self.id_wid, self.op_wid)
-        m1mod = FPMulStage1Mod(self.width, self.id_wid, self.op_wid)
+        m0mod = FPMulStage0Mod(self.width, self.pspec)
+        m1mod = FPMulStage1Mod(self.width, self.pspec)
 
         chain = StageChain([m0mod, m1mod])
         chain.setup(m, i)
index a13ec4ced369b7f20322a8a884e75ca413b74785..d735211cac725fb36519cb80735f5b3174580818 100644 (file)
@@ -18,11 +18,11 @@ from .mulstages import FPMulStages
 
 
 class FPMULBasePipe(ControlBase):
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         ControlBase.__init__(self)
-        self.pipe1 = FPMulSpecialCasesDeNorm(width, id_wid)
-        self.pipe2 = FPMulStages(width, id_wid)
-        self.pipe3 = FPNormToPack(width, id_wid)
+        self.pipe1 = FPMulSpecialCasesDeNorm(width, pspec)
+        self.pipe2 = FPMulStages(width, pspec)
+        self.pipe3 = FPNormToPack(width, pspec)
 
         self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
 
@@ -46,13 +46,16 @@ class FPMULMuxInOut(ReservationStations):
     """
     def __init__(self, width, num_rows, op_wid=0):
         self.width = width
+        self.pspec = {}
         self.id_wid = num_bits(width)
         self.op_wid = op_wid
-        self.alu = FPMULBasePipe(width, self.id_wid)
+        self.pspec['id_wid'] = self.id_wid
+        self.pspec['op_wid'] = self.op_wid
+        self.alu = FPMULBasePipe(width, self.pspec)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.id_wid, self.op_wid)
+        return FPPackData(self.width, self.pspec)
index 18f93dd23c8406dcd1b22feb2a033227cd6dfe1c..dab89b27a6bf53759e3715a2c5a066987f8d21c9 100644 (file)
@@ -18,18 +18,17 @@ class FPMulSpecialCasesMod(Elaboratable):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False, self.op_wid)
+        return FPSCData(self.width, self.pspec, False)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -96,7 +95,7 @@ class FPMulSpecialCasesMod(Elaboratable):
             m.d.comb += self.o.out_do_z.eq(0)
 
         m.d.comb += self.o.oz.eq(self.o.z.v)
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
@@ -118,7 +117,7 @@ class FPMulSpecialCases(FPState):
         """
         self.mod.setup(m, i, self.out_do_z)
         m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
-        m.d.sync += self.out_z.mid.eq(self.mod.o.mid)  # (and mid)
+        m.d.sync += self.out_z.ctx.eq(self.mod.o.ctx)  # (and context)
 
     def action(self, m):
         self.idsync(m)
@@ -132,25 +131,24 @@ class FPMulSpecialCasesDeNorm(FPState, SimpleHandshake):
     """ special cases: NaNs, infs, zeros, denormalised
     """
 
-    def __init__(self, width, id_wid, op_wid=None):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "special_cases")
         self.width = width
-        self.id_wid = id_wid
-        self.op_wid = op_wid
+        self.pspec = pspec
         SimpleHandshake.__init__(self, self) # pipe is its own stage
         self.out = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid, self.op_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False, self.op_wid)
+        return FPSCData(self.width, self.pspec, False)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
-        smod = FPMulSpecialCasesMod(self.width, self.id_wid)
-        dmod = FPAddDeNormMod(self.width, self.id_wid, False)
+        smod = FPMulSpecialCasesMod(self.width, self.pspec)
+        dmod = FPAddDeNormMod(self.width, self.pspec, False)
 
         chain = StageChain([smod, dmod])
         chain.setup(m, i)
index efc1e005f572301d31648d0349f286be8c0bdbd9..82e3b8ae8088f0bbf799698b6e4c12086eb645e1 100644 (file)
@@ -187,6 +187,8 @@ class CombMultiOutPipeline(MultiOutControlBase):
 
         # multiplexer id taken from n_mux
         mid = self.n_mux.m_id
+        print ("self.n_mux", self.n_mux)
+        print ("self.n_mux.m_id", self.n_mux.m_id)
 
         # temporaries
         p_valid_i = Signal(reset_less=True)
@@ -303,6 +305,7 @@ class CombMuxOutPipe(CombMultiOutPipeline):
         CombMultiOutPipeline.__init__(self, stage, n_len=n_len, n_mux=stage)
 
         # HACK: n-mux is also the stage... so set the muxid equal to input mid
+        print ("combmuxout", self.p.data_i.mid)
         stage.m_id = self.p.data_i.mid
 
 
index bdf14572f843078a72765e0ae469783fdf504e2f..9a50f65032b885614d9fbb390d5f1af4feb60960 100644 (file)
@@ -94,8 +94,8 @@ class Visitor2:
 
     def arrayproxy_iter2(self, ao, ai):
         for p in ai.ports():
+            print ("arrayproxy - p", p, p.name, ao)
             op = getattr(ao, p.name)
-            print ("arrayproxy - p", p, p.name)
             yield from self.iterator2(op, p)