tidyup, use FPModBaseChain and FPModBase
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 12:06:53 +0000 (13:06 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 12:06:53 +0000 (13:06 +0100)
src/ieee754/fpadd/addstages.py
src/ieee754/fpcommon/modbase.py
src/ieee754/fpdiv/div0.py
src/ieee754/fpdiv/div2.py
src/ieee754/fpmul/mulstages.py

index 489365831b1bdde691a9c715cf5316fa05dc7d78..170b37c66355033f01904b96a1a8ae36881b12fa 100644 (file)
@@ -4,45 +4,19 @@ Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
 
 """
 
-from nmigen import Module
-from nmigen.cli import main, verilog
+from ieee754.fpcommon.modbase import FPModBaseChain
 
-from nmutil.singlepipe import StageChain
-from ieee754.pipeline import DynamicPipe
-
-from ieee754.fpcommon.denorm import FPSCData
-from ieee754.fpcommon.postcalc import FPAddStage1Data
 from ieee754.fpadd.align import FPAddAlignSingleMod
 from ieee754.fpadd.add0 import FPAddStage0Mod
 from ieee754.fpadd.add1 import FPAddStage1Mod
 
 
-class FPAddAlignSingleAdd(DynamicPipe):
-
-    def __init__(self, pspec):
-        self.pspec = pspec
-        super().__init__(pspec)
-
-    def ispec(self):
-        return FPSCData(self.pspec, True)
-
-    def ospec(self):
-        return FPAddStage1Data(self.pspec) # AddStage1 ospec
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
+class FPAddAlignSingleAdd(FPModBaseChain):
 
+    def get_chain(self):
         # chain AddAlignSingle, AddStage0 and AddStage1
         mod = FPAddAlignSingleMod(self.pspec)
         a0mod = FPAddStage0Mod(self.pspec)
         a1mod = FPAddStage1Mod(self.pspec)
 
-        chain = StageChain([mod, a0mod, a1mod])
-        chain.setup(m, i)
-
-        self.o = a1mod.o
-
-    def process(self, i):
-        return self.o
-
+        return [mod, a0mod, a1mod]
index 0daa6f63fc311b79508581c6c45430511b0ff9d3..1b338747350de6ab52c6c947024a9f690c75594c 100644 (file)
@@ -1,4 +1,7 @@
 from nmigen import Elaboratable
+from ieee754.pipeline import DynamicPipe
+from nmutil.singlepipe import StageChain
+
 
 class FPModBase(Elaboratable):
     """FPModBase: common code between nearly every pipeline module
@@ -18,3 +21,30 @@ class FPModBase(Elaboratable):
         setattr(m.submodules, self.modname, self)
         m.d.comb += self.i.eq(i)
 
+
+class FPModBaseChain(DynamicPipe):
+    """FPModBaseChain: common code between stage-chained pipes
+    """
+    def __init__(self, pspec):
+        self.pspec = pspec
+        self.chain = self.get_chain()
+        super().__init__(pspec)
+
+    def ispec(self):
+        """ returns the input spec of the first module in the chain
+        """
+        return self.chain[0].ispec()
+
+    def ospec(self):
+        """ returns the output spec of the last module in the chain
+        """
+        return self.chain[-1].ospec()
+
+    def process(self, i):
+        return self.o # ... returned here (see setup comment below)
+
+    def setup(self, m, i):
+        """ links module to inputs and outputs
+        """
+        StageChain(self.chain).setup(m, i) # input linked here, through chain
+        self.o = self.chain[-1].o # output is the last thing in the chain...
index 4b9f25a953e3c88dc8dd24a006f0179ebda4651b..af0097c3e7081af433ce6a894b0693d176120d93 100644 (file)
@@ -13,15 +13,15 @@ Relevant bugreports:
 from nmigen import Module, Signal, Cat, Elaboratable, Const, Mux
 from nmigen.cli import main, verilog
 
+from ieee754.fpcommon.modbase import FPModBase
 from ieee754.fpcommon.fpbase import FPNumBaseRecord
-from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.getop import FPPipeContext
 from ieee754.div_rem_sqrt_rsqrt.div_pipe import DivPipeInputData
 from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation as DPCOp
 
 
-class FPDivStage0Mod(Elaboratable):
+class FPDivStage0Mod(FPModBase):
     """ DIV/SQRT/RSQRT "preparation" module.
 
         adjusts mantissa and exponent (sqrt/rsqrt exponent must be even),
@@ -32,9 +32,7 @@ class FPDivStage0Mod(Elaboratable):
     """
 
     def __init__(self, pspec):
-        self.pspec = pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "div0")
 
     def ispec(self):
         return FPSCData(self.pspec, False)
@@ -42,15 +40,6 @@ class FPDivStage0Mod(Elaboratable):
     def ospec(self):
         return DivPipeInputData(self.pspec)
 
-    def process(self, i):
-        return self.o
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.div0 = self
-        m.d.comb += self.i.eq(i)
-
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
@@ -118,22 +107,3 @@ class FPDivStage0Mod(Elaboratable):
         return m
 
 
-class FPDivStage0(FPState):
-    """ First stage of div.
-    """
-
-    def __init__(self, pspec):
-        FPState.__init__(self, "divider_0")
-        self.mod = FPDivStage0Mod(pspec)
-        self.o = self.mod.ospec()
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        self.mod.setup(m, i)
-
-        # NOTE: these could be done as combinatorial (merge div0+div1)
-        m.d.sync += self.o.eq(self.mod.o)
-
-    def action(self, m):
-        m.next = "divider_1"
index 5a26ace733309544088db31d40ba56dbff3e01c7..c8f26aa803eafbb93301768ee3d9dbcbd5955772 100644 (file)
@@ -9,15 +9,15 @@ Relevant bugreports:
 * http://bugs.libre-riscv.org/show_bug.cgi?id=44
 """
 
-from nmigen import Module, Signal, Elaboratable, Cat
+from nmigen import Module, Signal, Cat
 from nmigen.cli import main, verilog
 
-from ieee754.fpcommon.fpbase import FPState
+from ieee754.fpcommon.modbase import FPModBase
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 from ieee754.div_rem_sqrt_rsqrt.div_pipe import DivPipeOutputData
 
 
-class FPDivStage2Mod(FPState, Elaboratable):
+class FPDivStage2Mod(FPModBase):
     """ Last stage of div: preparation for normalisation.
 
         NOTE: this phase does NOT do ACTUAL DIV processing, it ONLY
@@ -25,9 +25,7 @@ class FPDivStage2Mod(FPState, Elaboratable):
     """
 
     def __init__(self, pspec):
-        self.pspec = pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "div1")
 
     def ispec(self):
         return DivPipeOutputData(self.pspec)  # Q/Rem in...
@@ -37,15 +35,6 @@ class FPDivStage2Mod(FPState, Elaboratable):
         # required for ongoing processing (normalisation, correction etc.)
         return FPAddStage1Data(self.pspec)  # out to post-process
 
-    def process(self, i):
-        return self.o
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.div1 = self
-        m.d.comb += self.i.eq(i)
-
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
@@ -117,25 +106,3 @@ class FPDivStage2Mod(FPState, Elaboratable):
         return m
 
 
-class FPDivStage2(FPState):
-
-    def __init__(self, pspec):
-        FPState.__init__(self, "divider_1")
-        self.mod = FPDivStage2Mod(pspec)
-        self.out_z = FPNumBaseRecord(pspec, False)
-        self.out_of = Overflow()
-        self.norm_stb = Signal()
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        self.mod.setup(m, i)
-
-        m.d.sync += self.norm_stb.eq(0)  # sets to zero when not in div1 state
-
-        m.d.sync += self.out_of.eq(self.mod.out_of)
-        m.d.sync += self.out_z.eq(self.mod.out_z)
-        m.d.sync += self.norm_stb.eq(1)
-
-    def action(self, m):
-        m.next = "normalise_1"
index 5ce17c1f0568da40d855b58ce17e511bcd8c90f1..fb809cbc1eebfda538bfbd1157a716d0e75a7b3d 100644 (file)
@@ -5,38 +5,19 @@ from nmigen.cli import main, verilog
 
 from nmutil.singlepipe import StageChain
 
-from ieee754.pipeline import DynamicPipe
+from ieee754.fpcommon.modbase import FPModBaseChain
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 from ieee754.fpmul.mul0 import FPMulStage0Mod
 from ieee754.fpmul.mul1 import FPMulStage1Mod
 
 
-class FPMulStages(DynamicPipe):
-
-    def __init__(self, pspec):
-        self.pspec = pspec
-        super().__init__(pspec)
-
-    def ispec(self):
-        return FPSCData(self.pspec, False)
-
-    def ospec(self):
-        return FPAddStage1Data(self.pspec)
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
+class FPMulStages(FPModBaseChain):
 
+    def get_chain(self):
         # chain MulStage0 and MulStage1
         m0mod = FPMulStage0Mod(self.pspec)
         m1mod = FPMulStage1Mod(self.pspec)
 
-        chain = StageChain([m0mod, m1mod])
-        chain.setup(m, i)
-
-        self.o = m1mod.o
-
-    def process(self, i):
-        return self.o
+        return [m0mod, m1mod]