tidyup of FPAdd Align
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 21:05:43 +0000 (22:05 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Jul 2019 21:05:43 +0000 (22:05 +0100)
src/ieee754/fpadd/align.py

index 7bdf160504384a32e3f77a8fd2b30ad3d8ee71e0..c6071fe36c70a11a9f7666e1f69398c94c001664 100644 (file)
@@ -10,27 +10,12 @@ from ieee754.fpcommon.fpbase import FPNumBaseRecord
 from ieee754.fpcommon.fpbase import MultiShiftRMerge
 from ieee754.fpcommon.denorm import FPSCData
 from ieee754.fpcommon.getop import FPPipeContext
-
-
-class FPNumIn2Ops:
-
-    def __init__(self, pspec):
-        width = pspec.width
-        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.ctx = FPPipeContext(pspec)
-        self.muxid = self.ctx.muxid
-
-    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.ctx.eq(i.ctx)]
+from ieee754.fpcommon.pscdata import FPSCData
 
 
 class FPAddAlignMultiMod:
-
+    """Module to do mantissa alignment shift in multiple cycles
+    """
     def __init__(self, width):
         self.in_a = FPNumBaseRecord(width)
         self.in_b = FPNumBaseRecord(width)
@@ -39,35 +24,25 @@ class FPAddAlignMultiMod:
         self.exp_eq = Signal(reset_less=True)
 
     def elaborate(self, platform):
-        # This one however (single-cycle) will do the shift
-        # in one go.
-
         m = Module()
-
-        #m.submodules.align_in_a = self.in_a
-        #m.submodules.align_in_b = self.in_b
-        #m.submodules.align_out_a = self.out_a
-        #m.submodules.align_out_b = self.out_b
-
-        # NOTE: this does *not* do single-cycle multi-shifting,
-        #       it *STAYS* in the align state until exponents match
+        comb = m.d.comb
 
         # exponent of a greater than b: shift b down
-        m.d.comb += self.exp_eq.eq(0)
-        m.d.comb += self.out_a.eq(self.in_a)
-        m.d.comb += self.out_b.eq(self.in_b)
+        comb += self.exp_eq.eq(0)
+        comb += self.out_a.eq(self.in_a)
+        comb += self.out_b.eq(self.in_b)
         agtb = Signal(reset_less=True)
         altb = Signal(reset_less=True)
-        m.d.comb += agtb.eq(self.in_a.e > self.in_b.e)
-        m.d.comb += altb.eq(self.in_a.e < self.in_b.e)
+        comb += agtb.eq(self.in_a.e > self.in_b.e)
+        comb += altb.eq(self.in_a.e < self.in_b.e)
         with m.If(agtb):
-            m.d.comb += self.out_b.shift_down(self.in_b)
+            comb += self.out_b.shift_down(self.in_b)
         # exponent of b greater than a: shift a down
         with m.Elif(altb):
-            m.d.comb += self.out_a.shift_down(self.in_a)
+            comb += self.out_a.shift_down(self.in_a)
         # exponents equal: move to next stage.
         with m.Else():
-            m.d.comb += self.exp_eq.eq(1)
+            comb += self.exp_eq.eq(1)
         return m
 
 
@@ -80,7 +55,7 @@ class FPAddAlignSingleMod(PipeModBase):
         return FPSCData(self.pspec, True)
 
     def ospec(self):
-        return FPNumIn2Ops(self.pspec)
+        return FPSCData(self.pspec, True)
 
     def elaborate(self, platform):
         """ Aligns A against B or B against A, depending on which has the
@@ -92,6 +67,7 @@ class FPAddAlignSingleMod(PipeModBase):
             needs to be aligned against the other
         """
         m = Module()
+        comb = m.d.comb
 
         # temporary (muxed) input and output to be shifted
         width = self.pspec.width
@@ -101,49 +77,50 @@ class FPAddAlignSingleMod(PipeModBase):
         msr = MultiShiftRMerge(self.i.a.m_width, espec)
         m.submodules.multishift_r = msr
 
+        # temporaries
         ediff = Signal(espec, reset_less=True)
         ediffr = Signal(espec, reset_less=True)
         tdiff = Signal(espec, reset_less=True)
         elz = Signal(reset_less=True)
         egz = Signal(reset_less=True)
 
-        # connect multi-shifter to t_inp/out mantissa (and tdiff)
-        m.d.comb += msr.inp.eq(t_inp.m)
-        m.d.comb += msr.diff.eq(tdiff)
-        m.d.comb += t_out.m.eq(msr.m)
-        m.d.comb += t_out.e.eq(t_inp.e + tdiff)
-        m.d.comb += t_out.s.eq(t_inp.s)
-
-        m.d.comb += ediff.eq(self.i.a.e - self.i.b.e)
-        m.d.comb += ediffr.eq(self.i.b.e - self.i.a.e)
-        m.d.comb += elz.eq(self.i.a.e < self.i.b.e)
-        m.d.comb += egz.eq(self.i.a.e > self.i.b.e)
-
-        # default: A-exp == B-exp, A and B untouched (fall through)
-        m.d.comb += self.o.a.eq(self.i.a)
-        m.d.comb += self.o.b.eq(self.i.b)
-        # only one shifter (muxed)
-        #m.d.comb += t_out.shift_down_multi(tdiff, t_inp)
-        # exponent of a greater than b: shift b down
         with m.If(~self.i.out_do_z):
+            # connect multi-shifter to t_inp/out mantissa (and tdiff)
+            # (only one: input/output is muxed)
+            comb += msr.inp.eq(t_inp.m)
+            comb += msr.diff.eq(tdiff)
+            comb += t_out.m.eq(msr.m)
+            comb += t_out.e.eq(t_inp.e + tdiff)
+            comb += t_out.s.eq(t_inp.s)
+
+            comb += ediff.eq(self.i.a.e - self.i.b.e)   # a - b
+            comb += ediffr.eq(self.i.b.e - self.i.a.e)  # b - a
+            comb += elz.eq(self.i.a.e < self.i.b.e)     # ae < be
+            comb += egz.eq(self.i.a.e > self.i.b.e)     # ae > be
+
+            # default: A-exp == B-exp, A and B untouched (fall through)
+            comb += self.o.a.eq(self.i.a)
+            comb += self.o.b.eq(self.i.b)
+
+            # exponent of a greater than b: shift b down
             with m.If(egz):
-                m.d.comb += [t_inp.eq(self.i.b),
+                comb += [t_inp.eq(self.i.b),
                              tdiff.eq(ediff),
                              self.o.b.eq(t_out),
                              self.o.b.s.eq(self.i.b.s), # whoops forgot sign
                             ]
             # exponent of b greater than a: shift a down
             with m.Elif(elz):
-                m.d.comb += [t_inp.eq(self.i.a),
+                comb += [t_inp.eq(self.i.a),
                              tdiff.eq(ediffr),
                              self.o.a.eq(t_out),
                              self.o.a.s.eq(self.i.a.s), # whoops forgot sign
                             ]
 
-        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)
+        comb += self.o.ctx.eq(self.i.ctx)
+        comb += self.o.z.eq(self.i.z)
+        comb += self.o.out_do_z.eq(self.i.out_do_z)
+        comb += self.o.oz.eq(self.i.oz)
 
         return m