cleanup fpmul
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 11:54:41 +0000 (12:54 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 11:54:41 +0000 (12:54 +0100)
src/ieee754/fpmul/align.py
src/ieee754/fpmul/mul0.py
src/ieee754/fpmul/mul1.py
src/ieee754/fpmul/mulstages.py

index a32024e014de49bb3cce5c1cc6e79f0fbbf28d25..9284926bb31bbe41abfa1167636fa6ec7fe11970 100644 (file)
@@ -1,26 +1,22 @@
 # IEEE Floating Point Multiplier
 
 # IEEE Floating Point Multiplier
 
-from nmigen import Module, Signal, Cat, Mux, Elaboratable
+from nmigen import Module, Signal, Cat, Mux
 from nmigen.cli import main, verilog
 from math import log
 
 from nmigen.cli import main, verilog
 from math import log
 
-from nmutil.singlepipe import StageChain
-
-from ieee754.fpcommon.fpbase import (Overflow, OverflowMod,
-                                     FPNumBase, FPNumBaseRecord)
+from ieee754.fpcommon.modbase import FPModBase
+from ieee754.fpcommon.fpbase import FPNumBase
 from ieee754.fpcommon.getop import FPPipeContext
 from ieee754.fpcommon.msbhigh import FPMSBHigh
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 
 
 from ieee754.fpcommon.getop import FPPipeContext
 from ieee754.fpcommon.msbhigh import FPMSBHigh
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 
 
-class FPAlignModSingle(Elaboratable):
+class FPAlignModSingle(FPModBase):
 
     def __init__(self, pspec, e_extra=False):
 
     def __init__(self, pspec, e_extra=False):
-        self.pspec = pspec
         self.e_extra = e_extra
         self.e_extra = e_extra
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "align")
 
     def ispec(self):
         return FPSCData(self.pspec, False)
 
     def ispec(self):
         return FPSCData(self.pspec, False)
@@ -28,17 +24,9 @@ class FPAlignModSingle(Elaboratable):
     def ospec(self):
         return FPSCData(self.pspec, False)
 
     def ospec(self):
         return FPSCData(self.pspec, False)
 
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.align = self
-        m.d.comb += self.i.eq(i)
-
-    def process(self, i):
-        return self.o
-
     def elaborate(self, platform):
         m = Module()
     def elaborate(self, platform):
         m = Module()
+        comb = m.d.comb
 
         self.o.a.m.name = "o_a_m"
         self.o.b.m.name = "o_b_m"
 
         self.o.a.m.name = "o_a_m"
         self.o.b.m.name = "o_b_m"
@@ -55,38 +43,36 @@ class FPAlignModSingle(Elaboratable):
         m.submodules.norm_pe_b = msb_b
 
         # connect to msb_a/b module
         m.submodules.norm_pe_b = msb_b
 
         # connect to msb_a/b module
-        m.d.comb += msb_a.m_in.eq(insel_a.m)
-        m.d.comb += msb_a.e_in.eq(insel_a.e)
-        m.d.comb += msb_b.m_in.eq(insel_b.m)
-        m.d.comb += msb_b.e_in.eq(insel_b.e)
+        comb += msb_a.m_in.eq(insel_a.m)
+        comb += msb_a.e_in.eq(insel_a.e)
+        comb += msb_b.m_in.eq(insel_b.m)
+        comb += msb_b.e_in.eq(insel_b.e)
 
         # copy input to output (overridden below)
 
         # copy input to output (overridden below)
-        m.d.comb += self.o.a.eq(insel_a)
-        m.d.comb += self.o.b.eq(insel_b)
+        comb += self.o.a.eq(insel_a)
+        comb += self.o.b.eq(insel_b)
 
         # normalisation increase/decrease conditions
         decrease_a = Signal(reset_less=True)
         decrease_b = Signal(reset_less=True)
 
         # normalisation increase/decrease conditions
         decrease_a = Signal(reset_less=True)
         decrease_b = Signal(reset_less=True)
-        m.d.comb += decrease_a.eq(insel_a.m_msbzero)
-        m.d.comb += decrease_b.eq(insel_b.m_msbzero)
+        comb += decrease_a.eq(insel_a.m_msbzero)
+        comb += decrease_b.eq(insel_b.m_msbzero)
 
 
-        # ok this is near-identical to FPNorm.  TODO: modularise
+        # ok this is near-identical to FPNorm: use same class (FPMSBHigh)
         with m.If(~self.i.out_do_z):
             with m.If(decrease_a):
         with m.If(~self.i.out_do_z):
             with m.If(decrease_a):
-                m.d.comb += [
+                comb += [
                     self.o.a.e.eq(msb_a.e_out),
                     self.o.a.m.eq(msb_a.m_out),
                 ]
             with m.If(decrease_b):
                     self.o.a.e.eq(msb_a.e_out),
                     self.o.a.m.eq(msb_a.m_out),
                 ]
             with m.If(decrease_b):
-                m.d.comb += [
+                comb += [
                     self.o.b.e.eq(msb_b.e_out),
                     self.o.b.m.eq(msb_b.m_out),
                 ]
 
                     self.o.b.e.eq(msb_b.e_out),
                     self.o.b.m.eq(msb_b.m_out),
                 ]
 
-        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)
+        comb += self.o.ctx.eq(self.i.ctx)
+        comb += self.o.out_do_z.eq(self.i.out_do_z)
+        comb += self.o.oz.eq(self.i.oz)
 
         return m
 
         return m
-
-
index 916d789847b1ca314716af870de9752deec4645c..0ed25035a48e923d824f4be64d4f7e72b670667e 100644 (file)
@@ -7,6 +7,7 @@ Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
 from nmigen import Module, Signal, Cat, Elaboratable
 from nmigen.cli import main, verilog
 
 from nmigen import Module, Signal, Cat, Elaboratable
 from nmigen.cli import main, verilog
 
+from ieee754.fpcommon.modbase import FPModBase
 from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.getop import FPPipeContext
 from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.getop import FPPipeContext
@@ -29,12 +30,10 @@ class FPMulStage0Data:
                 self.product.eq(i.product), self.ctx.eq(i.ctx)]
 
 
                 self.product.eq(i.product), self.ctx.eq(i.ctx)]
 
 
-class FPMulStage0Mod(Elaboratable):
+class FPMulStage0Mod(FPModBase):
 
     def __init__(self, pspec):
 
     def __init__(self, pspec):
-        self.pspec = pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "mul0")
 
     def ispec(self):
         return FPSCData(self.pspec, False)
 
     def ispec(self):
         return FPSCData(self.pspec, False)
@@ -42,33 +41,26 @@ class FPMulStage0Mod(Elaboratable):
     def ospec(self):
         return FPMulStage0Data(self.pspec)
 
     def ospec(self):
         return FPMulStage0Data(self.pspec)
 
-    def process(self, i):
-        return self.o
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.mul0 = self
-        m.d.comb += self.i.eq(i)
-
     def elaborate(self, platform):
         m = Module()
     def elaborate(self, platform):
         m = Module()
+        comb = m.d.comb
 
         # store intermediate tests (and zero-extended mantissas)
         am0 = Signal(len(self.i.a.m)+1, reset_less=True)
         bm0 = Signal(len(self.i.b.m)+1, reset_less=True)
 
         # store intermediate tests (and zero-extended mantissas)
         am0 = Signal(len(self.i.a.m)+1, reset_less=True)
         bm0 = Signal(len(self.i.b.m)+1, reset_less=True)
-        m.d.comb += [
+        comb += [
                      am0.eq(Cat(self.i.a.m, 0)),
                      bm0.eq(Cat(self.i.b.m, 0))
                     ]
         # same-sign (both negative or both positive) mul mantissas
         with m.If(~self.i.out_do_z):
                      am0.eq(Cat(self.i.a.m, 0)),
                      bm0.eq(Cat(self.i.b.m, 0))
                     ]
         # same-sign (both negative or both positive) mul mantissas
         with m.If(~self.i.out_do_z):
-            m.d.comb += [self.o.z.e.eq(self.i.a.e + self.i.b.e + 1),
+            comb += [self.o.z.e.eq(self.i.a.e + self.i.b.e + 1),
                          self.o.product.eq(am0 * bm0 * 4),
                          self.o.z.s.eq(self.i.a.s ^ self.i.b.s)
                 ]
 
                          self.o.product.eq(am0 * bm0 * 4),
                          self.o.z.s.eq(self.i.a.s ^ self.i.b.s)
                 ]
 
-        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.ctx.eq(self.i.ctx)
+        comb += self.o.oz.eq(self.i.oz)
+        comb += self.o.out_do_z.eq(self.i.out_do_z)
+        comb += self.o.ctx.eq(self.i.ctx)
+
         return m
         return m
index 6aa205616367c9b9f1ea1703d86f00dd7176d97f..98374fa55d3a2cd03a626e4b6be38745b28d46b9 100644 (file)
@@ -7,18 +7,17 @@ Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
 from nmigen import Module, Signal, Elaboratable
 from nmigen.cli import main, verilog
 
 from nmigen import Module, Signal, Elaboratable
 from nmigen.cli import main, verilog
 
+from ieee754.fpcommon.modbase import FPModBase
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 from ieee754.fpmul.mul0 import FPMulStage0Data
 
 
 from ieee754.fpcommon.postcalc import FPAddStage1Data
 from ieee754.fpmul.mul0 import FPMulStage0Data
 
 
-class FPMulStage1Mod(Elaboratable):
+class FPMulStage1Mod(FPModBase):
     """ Second stage of mul: preparation for normalisation.
     """
 
     def __init__(self, pspec):
     """ Second stage of mul: preparation for normalisation.
     """
 
     def __init__(self, pspec):
-        self.pspec = pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "mul1")
 
     def ispec(self):
         return FPMulStage0Data(self.pspec)
 
     def ispec(self):
         return FPMulStage0Data(self.pspec)
@@ -26,18 +25,11 @@ class FPMulStage1Mod(Elaboratable):
     def ospec(self):
         return FPAddStage1Data(self.pspec)
 
     def ospec(self):
         return FPAddStage1Data(self.pspec)
 
-    def process(self, i):
-        return self.o
-
-    def setup(self, m, i):
-        """ links module to inputs and outputs
-        """
-        m.submodules.mul1 = self
-        m.d.comb += self.i.eq(i)
-
     def elaborate(self, platform):
         m = Module()
     def elaborate(self, platform):
         m = Module()
-        m.d.comb += self.o.z.eq(self.i.z)
+        comb = m.d.comb
+
+        comb += self.o.z.eq(self.i.z)
         with m.If(~self.i.out_do_z):
             # results are in the range 0.25 to 0.999999999999
             # sometimes the MSB will be zero, (0.5 * 0.5 = 0.25 which
         with m.If(~self.i.out_do_z):
             # results are in the range 0.25 to 0.999999999999
             # sometimes the MSB will be zero, (0.5 * 0.5 = 0.25 which
@@ -45,16 +37,16 @@ class FPMulStage1Mod(Elaboratable):
             # to shift the mantissa up (and reduce the exponent by 1)
             p = Signal(len(self.i.product), reset_less=True)
             with m.If(self.i.product[-1]):
             # to shift the mantissa up (and reduce the exponent by 1)
             p = Signal(len(self.i.product), reset_less=True)
             with m.If(self.i.product[-1]):
-                m.d.comb += p.eq(self.i.product)
+                comb += p.eq(self.i.product)
             with m.Else():
                 # get 1 bit of extra accuracy if the mantissa top bit is zero
             with m.Else():
                 # get 1 bit of extra accuracy if the mantissa top bit is zero
-                m.d.comb += p.eq(self.i.product<<1)
-                m.d.comb += self.o.z.e.eq(self.i.z.e-1)
+                comb += p.eq(self.i.product<<1)
+                comb += self.o.z.e.eq(self.i.z.e-1)
 
             # top bits are mantissa, then guard and round, and the rest of
             # the product is sticky
             mw = self.o.z.m_width
 
             # top bits are mantissa, then guard and round, and the rest of
             # the product is sticky
             mw = self.o.z.m_width
-            m.d.comb += [
+            comb += [
                 self.o.z.m.eq(p[mw+2:]),            # mantissa
                 self.o.of.m0.eq(p[mw+2]),           # copy of LSB
                 self.o.of.guard.eq(p[mw+1]),        # guard
                 self.o.z.m.eq(p[mw+2:]),            # mantissa
                 self.o.of.m0.eq(p[mw+2]),           # copy of LSB
                 self.o.of.guard.eq(p[mw+1]),        # guard
@@ -62,8 +54,8 @@ class FPMulStage1Mod(Elaboratable):
                 self.o.of.sticky.eq(p[0:mw].bool()) # sticky
             ]
 
                 self.o.of.sticky.eq(p[0:mw].bool()) # sticky
             ]
 
-        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.ctx.eq(self.i.ctx)
+        comb += self.o.out_do_z.eq(self.i.out_do_z)
+        comb += self.o.oz.eq(self.i.oz)
+        comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
         return m
index 2e96ed3b668e1151e5bf68e7271af6ba15f13132..5ce17c1f0568da40d855b58ce17e511bcd8c90f1 100644 (file)
@@ -17,7 +17,6 @@ class FPMulStages(DynamicPipe):
     def __init__(self, pspec):
         self.pspec = pspec
         super().__init__(pspec)
     def __init__(self, pspec):
         self.pspec = pspec
         super().__init__(pspec)
-        self.m1o = self.ospec()
 
     def ispec(self):
         return FPSCData(self.pspec, False)
 
     def ispec(self):
         return FPSCData(self.pspec, False)