use ispec and ospec in FPNormaliseModSingle
[ieee754fpu.git] / src / add / nmigen_add_experiment.py
index ef783cae007eb89e763f7224747faf1db1954b0e..5d5a9933250434778592112bfa7bed17c5ed96f1 100644 (file)
@@ -711,13 +711,10 @@ class FPAddAlignSingleAdd(FPState, FPID):
         self.o = self.mod.ospec()
 
         self.a0mod = FPAddStage0Mod(width)
-        self.a0_out_z = FPNumBase(width, False)
-        self.out_tot = Signal(self.a0_out_z.m_width + 4, reset_less=True)
-        self.a0_out_z = FPNumBase(width, False)
+        self.a0o = self.a0mod.ospec()
 
         self.a1mod = FPAddStage1Mod(width)
-        self.out_z = FPNumBase(width, False)
-        self.out_of = Overflow()
+        self.a1o = self.a1mod.ospec()
 
     def setup(self, m, in_a, in_b, in_mid):
         """ links module to inputs and outputs
@@ -726,18 +723,16 @@ class FPAddAlignSingleAdd(FPState, FPID):
         m.d.comb += self.o.eq(self.mod.o)
 
         self.a0mod.setup(m, self.o.a, self.o.b)
-        m.d.comb += self.a0_out_z.eq(self.a0mod.o.z)
-        m.d.comb += self.out_tot.eq(self.a0mod.o.tot)
+        m.d.comb += self.a0o.eq(self.a0mod.o)
 
-        self.a1mod.setup(m, self.out_tot, self.a0_out_z)
+        self.a1mod.setup(m, self.a0o.tot, self.a0o.z)
 
         if self.in_mid is not None:
             m.d.comb += self.in_mid.eq(in_mid)
 
     def action(self, m):
         self.idsync(m)
-        m.d.sync += self.out_of.eq(self.a1mod.out_of)
-        m.d.sync += self.out_z.eq(self.a1mod.out_z)
+        m.d.sync += self.a1o.eq(self.a1mod.o)
         m.next = "normalise_1"
 
 
@@ -820,8 +815,7 @@ class FPAddStage0(FPState, FPID):
         FPState.__init__(self, "add_0")
         FPID.__init__(self, id_wid)
         self.mod = FPAddStage0Mod(width)
-        self.out_z = FPNumBase(width, False)
-        self.out_tot = Signal(self.out_z.m_width + 4, reset_less=True)
+        self.o = self.mod.ospec()
 
     def setup(self, m, in_a, in_b, in_mid):
         """ links module to inputs and outputs
@@ -833,31 +827,45 @@ class FPAddStage0(FPState, FPID):
     def action(self, m):
         self.idsync(m)
         # NOTE: these could be done as combinatorial (merge add0+add1)
-        m.d.sync += self.out_z.eq(self.mod.out_z)
-        m.d.sync += self.out_tot.eq(self.mod.out_tot)
+        m.d.sync += self.o.eq(self.mod.o)
         m.next = "add_1"
 
 
+class FPAddStage1Data:
+
+    def __init__(self, width):
+        self.z = FPNumBase(width, False)
+        self.of = Overflow()
+
+    def eq(self, i):
+        return [self.z.eq(i.z), self.of.eq(i.of)]
+
+
+
 class FPAddStage1Mod(FPState):
     """ Second stage of add: preparation for normalisation.
         detects when tot sum is too big (tot[27] is kinda a carry bit)
     """
 
     def __init__(self, width):
-        self.out_norm = Signal(reset_less=True)
-        self.in_z = FPNumBase(width, False)
-        self.in_tot = Signal(self.in_z.m_width + 4, reset_less=True)
-        self.out_z = FPNumBase(width, False)
-        self.out_of = Overflow()
+        self.width = width
+        self.i = self.ispec()
+        self.o = self.ospec()
+
+    def ispec(self):
+        return FPAddStage0Data(self.width)
+
+    def ospec(self):
+        return FPAddStage1Data(self.width)
 
     def setup(self, m, in_tot, in_z):
         """ links module to inputs and outputs
         """
         m.submodules.add1 = self
-        m.submodules.add1_out_overflow = self.out_of
+        m.submodules.add1_out_overflow = self.o.of
 
-        m.d.comb += self.in_z.eq(in_z)
-        m.d.comb += self.in_tot.eq(in_tot)
+        m.d.comb += self.i.z.eq(in_z)
+        m.d.comb += self.i.tot.eq(in_tot)
 
     def elaborate(self, platform):
         m = Module()
@@ -865,25 +873,25 @@ class FPAddStage1Mod(FPState):
         #m.submodules.norm1_out_overflow = self.out_of
         #m.submodules.norm1_in_z = self.in_z
         #m.submodules.norm1_out_z = self.out_z
-        m.d.comb += self.out_z.eq(self.in_z)
+        m.d.comb += self.o.z.eq(self.i.z)
         # tot[-1] (MSB) gets set when the sum overflows. shift result down
-        with m.If(self.in_tot[-1]):
+        with m.If(self.i.tot[-1]):
             m.d.comb += [
-                self.out_z.m.eq(self.in_tot[4:]),
-                self.out_of.m0.eq(self.in_tot[4]),
-                self.out_of.guard.eq(self.in_tot[3]),
-                self.out_of.round_bit.eq(self.in_tot[2]),
-                self.out_of.sticky.eq(self.in_tot[1] | self.in_tot[0]),
-                self.out_z.e.eq(self.in_z.e + 1)
+                self.o.z.m.eq(self.i.tot[4:]),
+                self.o.of.m0.eq(self.i.tot[4]),
+                self.o.of.guard.eq(self.i.tot[3]),
+                self.o.of.round_bit.eq(self.i.tot[2]),
+                self.o.of.sticky.eq(self.i.tot[1] | self.i.tot[0]),
+                self.o.z.e.eq(self.i.z.e + 1)
         ]
         # tot[-1] (MSB) zero case
         with m.Else():
             m.d.comb += [
-                self.out_z.m.eq(self.in_tot[3:]),
-                self.out_of.m0.eq(self.in_tot[3]),
-                self.out_of.guard.eq(self.in_tot[2]),
-                self.out_of.round_bit.eq(self.in_tot[1]),
-                self.out_of.sticky.eq(self.in_tot[0])
+                self.o.z.m.eq(self.i.tot[3:]),
+                self.o.of.m0.eq(self.i.tot[3]),
+                self.o.of.guard.eq(self.i.tot[2]),
+                self.o.of.round_bit.eq(self.i.tot[1]),
+                self.o.of.sticky.eq(self.i.tot[0])
         ]
         return m
 
@@ -920,8 +928,14 @@ class FPNormaliseModSingle:
 
     def __init__(self, width):
         self.width = width
-        self.in_z = FPNumBase(width, False)
-        self.out_z = FPNumBase(width, False)
+        self.in_z = self.ispec()
+        self.out_z = self.ospec()
+
+    def ispec(self):
+        return FPNumBase(self.width, False)
+
+    def ospec(self):
+        return FPNumBase(self.width, False)
 
     def setup(self, m, in_z, out_z, modname):
         """ links module to inputs and outputs
@@ -955,7 +969,7 @@ class FPNormaliseModSingle:
         # initialise out from in (overridden below)
         m.d.comb += self.out_z.eq(in_z)
         m.d.comb += self.out_of.eq(in_of)
-        # normalisation increase/decrease conditions
+        # normalisation decrease condition
         decrease = Signal(reset_less=True)
         m.d.comb += decrease.eq(in_z.m_msbzero)
         # decrease exponent
@@ -1083,7 +1097,6 @@ class FPNorm1ModMulti:
     def __init__(self, width, single_cycle=True):
         self.width = width
         self.in_select = Signal(reset_less=True)
-        self.out_norm = Signal(reset_less=True)
         self.in_z = FPNumBase(width, False)
         self.in_of = Overflow()
         self.temp_z = FPNumBase(width, False)
@@ -1554,7 +1567,7 @@ class FPADDBaseMod(FPID):
         alm.setup(m, sc.o.a, sc.o.b, sc.in_mid)
 
         n1 = self.add_state(FPNormToPack(self.width, self.id_wid))
-        n1.setup(m, alm.out_z, alm.out_of, alm.in_mid)
+        n1.setup(m, alm.a1o.z, alm.a1o.of, alm.in_mid)
 
         ppz = self.add_state(FPPutZ("pack_put_z", n1.out_z, self.out_z,
                                     n1.in_mid, self.out_mid))