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
 
-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 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
 
 
-class FPAlignModSingle(Elaboratable):
+class FPAlignModSingle(FPModBase):
 
     def __init__(self, pspec, e_extra=False):
-        self.pspec = pspec
         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)
@@ -28,17 +24,9 @@ class FPAlignModSingle(Elaboratable):
     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()
+        comb = m.d.comb
 
         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.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)
-        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)
-        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):
-                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):
-                m.d.comb += [
+                comb += [
                     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
-
-
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 ieee754.fpcommon.modbase import FPModBase
 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)]
 
 
-class FPMulStage0Mod(Elaboratable):
+class FPMulStage0Mod(FPModBase):
 
     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)
@@ -42,33 +41,26 @@ class FPMulStage0Mod(Elaboratable):
     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()
+        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)
-        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):
-            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)
                 ]
 
-        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
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 ieee754.fpcommon.modbase import FPModBase
 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):
-        self.pspec = pspec
-        self.i = self.ispec()
-        self.o = self.ospec()
+        super().__init__(pspec, "mul1")
 
     def ispec(self):
         return FPMulStage0Data(self.pspec)
@@ -26,18 +25,11 @@ class FPMulStage1Mod(Elaboratable):
     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()
-        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
@@ -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]):
-                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
-                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
-            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
@@ -62,8 +54,8 @@ class FPMulStage1Mod(Elaboratable):
                 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
index 2e96ed3b668e1151e5bf68e7271af6ba15f13132..5ce17c1f0568da40d855b58ce17e511bcd8c90f1 100644 (file)
@@ -17,7 +17,6 @@ class FPMulStages(DynamicPipe):
     def __init__(self, pspec):
         self.pspec = pspec
         super().__init__(pspec)
-        self.m1o = self.ospec()
 
     def ispec(self):
         return FPSCData(self.pspec, False)