add id to align
[ieee754fpu.git] / src / add / nmigen_add_experiment.py
index 02a9ba15938c7bd428fbd19a4f133756cc00ba62..f9d890014ff0388e3322758f7b3469b9e81744ff 100644 (file)
@@ -74,19 +74,6 @@ class FPGetOp(FPState):
             m.d.sync += self.in_op.ack.eq(1)
 
 
-class FPGetOpB(FPState):
-    """ gets operand b
-    """
-
-    def __init__(self, in_b, width):
-        FPState.__init__(self, "get_b")
-        self.in_b = in_b
-        self.b = FPNumIn(self.in_b, width)
-
-    def action(self, m):
-        self.get_op(m, self.in_b, self.b, "special_cases")
-
-
 class FPAddSpecialCasesMod:
     """ special cases: NaNs, infs, zeros, denormalised
         NOTE: some of these are unique to add.  see "Special Operations"
@@ -99,14 +86,6 @@ class FPAddSpecialCasesMod:
         self.out_z = FPNumOut(width, False)
         self.out_do_z = Signal(reset_less=True)
 
-    def setup(self, m, in_a, in_b, out_z, out_do_z):
-        """ links module to inputs and outputs
-        """
-        m.d.comb += self.in_a.copy(in_a)
-        m.d.comb += self.in_b.copy(in_b)
-        #m.d.comb += out_z.v.eq(self.out_z.v)
-        m.d.comb += out_do_z.eq(self.out_do_z)
-
     def elaborate(self, platform):
         m = Module()
 
@@ -192,19 +171,47 @@ class FPAddSpecialCasesMod:
         return m
 
 
-class FPAddSpecialCases(FPState):
+class FPID:
+    def __init__(self, id_wid):
+        self.id_wid = id_wid
+        if self.id_wid:
+            self.in_mid = Signal(width, reset_less)
+            self.out_mid = Signal(width, reset_less)
+        else:
+            self.in_mid = None
+            self.out_mid = None
+
+    def idsync(self, m):
+        if self.id_wid:
+            m.d.sync += self.out_mid.eq(self.in_mid)
+
+
+class FPAddSpecialCases(FPState, FPID):
     """ special cases: NaNs, infs, zeros, denormalised
         NOTE: some of these are unique to add.  see "Special Operations"
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width):
+    def __init__(self, width, id_wid):
         FPState.__init__(self, "special_cases")
+        FPID.__init__(self, id_wid)
         self.mod = FPAddSpecialCasesMod(width)
         self.out_z = FPNumOut(width, False)
         self.out_do_z = Signal(reset_less=True)
 
+    def setup(self, m, in_a, in_b, in_mid):
+        """ links module to inputs and outputs
+        """
+        m.submodules.specialcases = self.mod
+        m.d.comb += self.mod.in_a.copy(in_a)
+        m.d.comb += self.mod.in_b.copy(in_b)
+        #m.d.comb += self.out_z.v.eq(self.mod.out_z.v)
+        m.d.comb += self.out_do_z.eq(self.mod.out_do_z)
+        if self.in_mid:
+            m.d.comb += self.in_mid.eq(in_mid)
+
     def action(self, m):
+        self.idsync(m)
         with m.If(self.out_do_z):
             m.d.sync += self.out_z.v.eq(self.mod.out_z.v) # only take the output
             m.next = "put_z"
@@ -242,22 +249,26 @@ class FPAddDeNormMod(FPState):
         return m
 
 
-class FPAddDeNorm(FPState):
+class FPAddDeNorm(FPState, FPID):
 
-    def __init__(self, width):
+    def __init__(self, width, id_wid):
         FPState.__init__(self, "denormalise")
+        FPID.__init__(self, id_wid)
         self.mod = FPAddDeNormMod(width)
         self.out_a = FPNumBase(width)
         self.out_b = FPNumBase(width)
 
-    def setup(self, m, in_a, in_b):
+    def setup(self, m, in_a, in_b, in_mid):
         """ links module to inputs and outputs
         """
         m.submodules.denormalise = self.mod
         m.d.comb += self.mod.in_a.copy(in_a)
         m.d.comb += self.mod.in_b.copy(in_b)
+        if self.in_mid:
+            m.d.comb += self.in_mid.eq(in_mid)
 
     def action(self, m):
+        self.idsync(m)
         # Denormalised Number checks
         m.next = "align"
         m.d.sync += self.out_a.copy(self.mod.out_a)
@@ -306,16 +317,17 @@ class FPAddAlignMultiMod(FPState):
         return m
 
 
-class FPAddAlignMulti(FPState):
+class FPAddAlignMulti(FPState, FPID):
 
-    def __init__(self, width):
+    def __init__(self, width, id_wid):
+        FPID.__init__(self, id_wid)
         FPState.__init__(self, "align")
         self.mod = FPAddAlignMultiMod(width)
         self.out_a = FPNumIn(None, width)
         self.out_b = FPNumIn(None, width)
         self.exp_eq = Signal(reset_less=True)
 
-    def setup(self, m, in_a, in_b):
+    def setup(self, m, in_a, in_b, in_mid):
         """ links module to inputs and outputs
         """
         m.submodules.align = self.mod
@@ -324,8 +336,11 @@ class FPAddAlignMulti(FPState):
         #m.d.comb += self.out_a.copy(self.mod.out_a)
         #m.d.comb += self.out_b.copy(self.mod.out_b)
         m.d.comb += self.exp_eq.eq(self.mod.exp_eq)
+        if self.in_mid:
+            m.d.comb += self.in_mid.eq(in_mid)
 
     def action(self, m):
+        self.idsync(m)
         m.d.sync += self.out_a.copy(self.mod.out_a)
         m.d.sync += self.out_b.copy(self.mod.out_b)
         with m.If(self.exp_eq):
@@ -406,22 +421,26 @@ class FPAddAlignSingleMod:
         return m
 
 
-class FPAddAlignSingle(FPState):
+class FPAddAlignSingle(FPState, FPID):
 
-    def __init__(self, width):
+    def __init__(self, width, id_wid):
         FPState.__init__(self, "align")
+        FPID.__init__(self, id_wid)
         self.mod = FPAddAlignSingleMod(width)
         self.out_a = FPNumIn(None, width)
         self.out_b = FPNumIn(None, width)
 
-    def setup(self, m, in_a, in_b):
+    def setup(self, m, in_a, in_b, in_mid):
         """ links module to inputs and outputs
         """
         m.submodules.align = self.mod
         m.d.comb += self.mod.in_a.copy(in_a)
         m.d.comb += self.mod.in_b.copy(in_b)
+        if self.in_mid:
+            m.d.comb += self.in_mid.eq(in_mid)
 
     def action(self, m):
+        self.idsync(m)
         # NOTE: could be done as comb
         m.d.sync += self.out_a.copy(self.mod.out_a)
         m.d.sync += self.out_b.copy(self.mod.out_b)
@@ -843,11 +862,6 @@ class FPCorrectionsMod:
         m.d.comb += self.out_z.copy(self.in_z)
         with m.If(self.in_z.is_denormalised):
             m.d.comb += self.out_z.e.eq(self.in_z.N127)
-
-        #        with m.If(self.in_z.is_overflowed):
-        #            m.d.comb += self.out_z.inf(self.in_z.s)
-        #        with m.Else():
-        #            m.d.comb += self.out_z.create(self.in_z.s, self.in_z.e, self.in_z.m)
         return m
 
 
@@ -921,9 +935,16 @@ class FPPutZ(FPState):
             m.d.sync += self.out_z.stb.eq(1)
 
 
-class FPADD:
+class FPADD(FPID):
+
+    def __init__(self, width, id_wid=None, single_cycle=False):
+        """ IEEE754 FP Add
 
-    def __init__(self, width, single_cycle=False):
+            * width: bit-width of IEEE754.  supported: 16, 32, 64
+            * id_wid: an identifier that is sync-connected to the input
+            * single_cycle: True indicates each stage to complete in 1 clock
+        """
+        FPID.__init__(self, id_wid)
         self.width = width
         self.single_cycle = single_cycle
 
@@ -955,20 +976,18 @@ class FPADD:
         getb.setup(m, self.in_b)
         b = getb.out_op
 
-        sc = self.add_state(FPAddSpecialCases(self.width))
-        sc.mod.setup(m, a, b, sc.out_z, sc.out_do_z)
-        m.submodules.specialcases = sc.mod
+        sc = self.add_state(FPAddSpecialCases(self.width, self.id_wid))
+        sc.setup(m, a, b, self.in_mid)
 
-        dn = self.add_state(FPAddDeNorm(self.width))
-        dn.setup(m, a, b)
+        dn = self.add_state(FPAddDeNorm(self.width, self.id_wid))
+        dn.setup(m, a, b, sc.in_mid)
 
         if self.single_cycle:
-            alm = self.add_state(FPAddAlignSingle(self.width))
-            alm.setup(m, dn.out_a, dn.out_b)
+            alm = self.add_state(FPAddAlignSingle(self.width, self.id_wid))
+            alm.setup(m, dn.out_a, dn.out_b, dn.in_mid)
         else:
-            alm = self.add_state(FPAddAlignMulti(self.width))
-            #alm.set_inputs({"a": a, "b": b})
-            alm.setup(m, dn.out_a, dn.out_b)
+            alm = self.add_state(FPAddAlignMulti(self.width, self.id_wid))
+            alm.setup(m, dn.out_a, dn.out_b, dn.in_mid)
 
         add0 = self.add_state(FPAddStage0(self.width))
         add0.setup(m, alm.out_a, alm.out_b)