move align to separate class
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Feb 2019 09:14:22 +0000 (09:14 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Feb 2019 09:14:22 +0000 (09:14 +0000)
src/add/nmigen_add_experiment.py

index 8c08652ff9115d90989cf14e8154c106f4a23677..9a3b546562d933e67978bb1a598e62a8bd4eeb48 100644 (file)
@@ -119,6 +119,44 @@ class FPAddDeNorm(FPState):
         self.denormalise(m, self.a)
         self.denormalise(m, self.b)
 
+class FPAddAlignMulti(FPState):
+
+    def action(self, m):
+        # NOTE: this does *not* do single-cycle multi-shifting,
+        #       it *STAYS* in the align state until exponents match
+
+        # exponent of a greater than b: shift b down
+        with m.If(self.a.e > self.b.e):
+            m.d.sync += self.b.shift_down()
+        # exponent of b greater than a: shift a down
+        with m.Elif(self.a.e < self.b.e):
+            m.d.sync += self.a.shift_down()
+        # exponents equal: move to next stage.
+        with m.Else():
+            m.next = "add_0"
+
+
+class FPAddAlignSingle(FPState):
+
+    def action(self, m):
+        # This one however (single-cycle) will do the shift
+        # in one go.
+
+        # XXX TODO: the shifter used here is quite expensive
+        # having only one would be better
+
+        ediff = Signal((len(self.a.e), True), reset_less=True)
+        ediffr = Signal((len(self.a.e), True), reset_less=True)
+        m.d.comb += ediff.eq(self.a.e - self.b.e)
+        m.d.comb += ediffr.eq(self.b.e - self.a.e)
+        with m.If(ediff > 0):
+            m.d.sync += self.b.shift_down_multi(ediff)
+        # exponent of b greater than a: shift a down
+        with m.Elif(ediff < 0):
+            m.d.sync += self.a.shift_down_multi(ediffr)
+
+        m.next = "add_0"
+
 
 class FPADD(FPBase):
 
@@ -169,6 +207,13 @@ class FPADD(FPBase):
         dn.set_inputs({"a": a, "b": b})
         dn.set_outputs({"a": a, "b": b}) # XXX outputs same as inputs
 
+        if self.single_cycle:
+            alm = FPAddAlignSingle("align")
+        else:
+            alm = FPAddAlignMulti("align")
+        alm.set_inputs({"a": a, "b": b})
+        alm.set_outputs({"a": a, "b": b}) # XXX outputs same as inputs
+
         with m.FSM() as fsm:
 
             # ******
@@ -202,37 +247,7 @@ class FPADD(FPBase):
             # align.
 
             with m.State("align"):
-                if not self.single_cycle:
-                    # NOTE: this does *not* do single-cycle multi-shifting,
-                    #       it *STAYS* in the align state until exponents match
-
-                    # exponent of a greater than b: shift b down
-                    with m.If(a.e > b.e):
-                        m.d.sync += b.shift_down()
-                    # exponent of b greater than a: shift a down
-                    with m.Elif(a.e < b.e):
-                        m.d.sync += a.shift_down()
-                    # exponents equal: move to next stage.
-                    with m.Else():
-                        m.next = "add_0"
-                else:
-                    # This one however (single-cycle) will do the shift
-                    # in one go.
-
-                    # XXX TODO: the shifter used here is quite expensive
-                    # having only one would be better
-
-                    ediff = Signal((len(a.e), True), reset_less=True)
-                    ediffr = Signal((len(a.e), True), reset_less=True)
-                    m.d.comb += ediff.eq(a.e - b.e)
-                    m.d.comb += ediffr.eq(b.e - a.e)
-                    with m.If(ediff > 0):
-                        m.d.sync += b.shift_down_multi(ediff)
-                    # exponent of b greater than a: shift a down
-                    with m.Elif(ediff < 0):
-                        m.d.sync += a.shift_down_multi(ediffr)
-
-                    m.next = "add_0"
+                alm.action(m)
 
             # ******
             # First stage of add.  covers same-sign (add) and subtract