add single-cycle version of alignment process in fadd
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 17 Feb 2019 13:09:55 +0000 (13:09 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 17 Feb 2019 13:09:55 +0000 (13:09 +0000)
src/add/fpbase.py
src/add/nmigen_add_experiment.py
src/add/test_add.py

index cc5184df63a7910b35c6e8039bc5629f8f4b9dcf..48e93a01fa1decedbc3b24e0be7f700171cfc59a 100644 (file)
@@ -62,7 +62,7 @@ class FPNum:
             m_width += self.m_extra
         else:
             self.m_extra = 0
-        print (m_width, e_width, e_max, self.rmw, self.m_extra)
+        #print (m_width, e_width, e_max, self.rmw, self.m_extra)
         self.m_width = m_width
         self.e_width = e_width
         self.e_start = self.rmw - 1
@@ -88,7 +88,7 @@ class FPNum:
             a 10-bit number
         """
         args = [0] * self.m_extra + [v[0:self.e_start]] # pad with extra zeros
-        print ("decode", self.e_end)
+        #print ("decode", self.e_end)
         return [self.m.eq(Cat(*args)), # mantissa
                 self.e.eq(v[self.e_start:self.e_end] - self.P127), # exp
                 self.s.eq(v[-1]),                 # sign
index da3726828913024b7e4b3c0121100af7a7cf0fe1..8f075cf18075be165c22c506bb0e33bc5bdb3e72 100644 (file)
@@ -10,9 +10,10 @@ from fpbase import FPNum, FPOp, Overflow, FPBase
 
 class FPADD(FPBase):
 
-    def __init__(self, width):
+    def __init__(self, width, single_cycle=False):
         FPBase.__init__(self)
         self.width = width
+        self.single_cycle = single_cycle
 
         self.in_a  = FPOp(width)
         self.in_b  = FPOp(width)
@@ -94,18 +95,36 @@ class FPADD(FPBase):
                     self.denormalise(m, b)
 
             # ******
-            # align.  NOTE: this does *not* do single-cycle multi-shifting,
-            #         it *STAYS* in the align state until the exponents match
+            # align.
 
             with m.State("align"):
-                # exponent of a greater than b: increment b exp, shift b mant
-                with m.If(a.e > b.e):
-                    m.d.sync += b.shift_down()
-                # exponent of b greater than a: increment a exp, shift a mant
-                with m.Elif(a.e < b.e):
-                    m.d.sync += a.shift_down()
-                # exponents equal: move to next stage.
-                with m.Else():
+                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.
+
+                    ediff = Signal((len(a.e), True))
+                    ediffr = Signal((len(a.e), 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"
 
             # ******
index def8c4752b5cb6474fff725329a5b8b9387166f6..c5e16a60ae2b58f93dc67a37f821b36825ab59c4 100644 (file)
@@ -76,6 +76,6 @@ def testbench(dut):
     #yield from check_case(dut, 1, 1, 1)
 
 if __name__ == '__main__':
-    dut = FPADD(width=32)
+    dut = FPADD(width=32, single_cycle=True)
     run_simulation(dut, testbench(dut), vcd_name="test_add.vcd")