split out add0 stage into separate class
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Feb 2019 09:22:24 +0000 (09:22 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Feb 2019 09:22:24 +0000 (09:22 +0000)
src/add/nmigen_add_experiment.py

index 9a3b546562d933e67978bb1a598e62a8bd4eeb48..cf0fd92b91103b3383bcecb1c176299df6f27789 100644 (file)
@@ -119,6 +119,7 @@ class FPAddDeNorm(FPState):
         self.denormalise(m, self.a)
         self.denormalise(m, self.b)
 
+
 class FPAddAlignMulti(FPState):
 
     def action(self, m):
@@ -158,6 +159,35 @@ class FPAddAlignSingle(FPState):
         m.next = "add_0"
 
 
+class FPAddStage0(FPState):
+
+    def action(self, m):
+        """ First stage of add.  covers same-sign (add) and subtract
+            special-casing when mantissas are greater or equal, to
+            give greatest accuracy.
+        """
+        m.next = "add_1"
+        m.d.sync += self.z.e.eq(self.a.e)
+        # same-sign (both negative or both positive) add mantissas
+        with m.If(self.a.s == self.b.s):
+            m.d.sync += [
+                self.tot.eq(Cat(self.a.m, 0) + Cat(self.b.m, 0)),
+                self.z.s.eq(self.a.s)
+            ]
+        # a mantissa greater than b, use a
+        with m.Elif(self.a.m >= self.b.m):
+            m.d.sync += [
+                self.tot.eq(Cat(self.a.m, 0) - Cat(self.b.m, 0)),
+                self.z.s.eq(self.a.s)
+            ]
+        # b mantissa greater than a, use b
+        with m.Else():
+            m.d.sync += [
+                self.tot.eq(Cat(self.b.m, 0) - Cat(self.a.m, 0)),
+                self.z.s.eq(self.b.s)
+        ]
+
+
 class FPADD(FPBase):
 
     def __init__(self, width, single_cycle=False):
@@ -214,6 +244,10 @@ class FPADD(FPBase):
         alm.set_inputs({"a": a, "b": b})
         alm.set_outputs({"a": a, "b": b}) # XXX outputs same as inputs
 
+        add0 = FPAddStage0("add_0")
+        add0.set_inputs({"a": a, "b": b})
+        add0.set_outputs({"z": z, "tot": tot})
+
         with m.FSM() as fsm:
 
             # ******
@@ -255,26 +289,7 @@ class FPADD(FPBase):
             # give greatest accuracy.
 
             with m.State("add_0"):
-                m.next = "add_1"
-                m.d.sync += z.e.eq(a.e)
-                # same-sign (both negative or both positive) add mantissas
-                with m.If(a.s == b.s):
-                    m.d.sync += [
-                        tot.eq(Cat(a.m, 0) + Cat(b.m, 0)),
-                        z.s.eq(a.s)
-                    ]
-                # a mantissa greater than b, use a
-                with m.Elif(a.m >= b.m):
-                    m.d.sync += [
-                        tot.eq(Cat(a.m, 0) - Cat(b.m, 0)),
-                        z.s.eq(a.s)
-                    ]
-                # b mantissa greater than a, use b
-                with m.Else():
-                    m.d.sync += [
-                        tot.eq(Cat(b.m, 0) - Cat(a.m, 0)),
-                        z.s.eq(b.s)
-                ]
+                add0.action(m)
 
             # ******
             # Second stage of add: preparation for normalisation.