Merge branch 'master' of ssh://libre-riscv.org:922/ieee754fpu
authorAleksandar Kostovic <alexandar.kostovic@gmail.com>
Thu, 14 Feb 2019 09:17:13 +0000 (10:17 +0100)
committerAleksandar Kostovic <alexandar.kostovic@gmail.com>
Thu, 14 Feb 2019 09:17:13 +0000 (10:17 +0100)
src/add/nmigen_add_experiment.py

index df100d1cf62f7317ed97d4491ad7f90a3a0d5e40..4ee76bb99c59d63c4011291ff22396eaf5443c91 100644 (file)
@@ -27,6 +27,13 @@ class FPADD:
         s_in_a_ack   = Signal()
         s_in_b_ack   = Signal()
 
+    def create_z(self, z, s, e, m):
+        return [
+          z[31].eq(s),    # sign
+          z[23:31].eq(e), # exp
+          z[0:23].eq(m)   # mantissa
+        ]
+
     def get_fragment(self, platform):
         m = Module()
 
@@ -110,65 +117,42 @@ class FPADD:
                 with m.If(((a_e == 128) & (a_m != 0)) | \
                           ((b_e == 128) & (b_m != 0))):
                     m.next = "put_z"
-                    m.d.sync += [
-                          z[31].eq(1),      # sign: 1
-                          z[23:31].eq(255), # exp: 0b11111...
-                          z[22].eq(1),      # mantissa top bit: 1
-                          z[0:22].eq(0)     # mantissa rest: 0b0000...
-                    ]
+                    m.d.sync += self.create_z(z, 1, 255, 1<<22)
 
                 # if a is inf return inf (or NaN)
                 with m.Elif(a_e == 128):
                     m.next = "put_z"
-                    m.d.sync += [
-                        z[31].eq(a_s),    # sign: a_s
-                        z[23:31].eq(255), # exp: 0b11111...
-                        z[0:23].eq(0)     # mantissa rest: 0b0000...
-                    ]
+                    m.d.sync += self.create_z(z, a_s, 255, 0)
                     # if a is inf and signs don't match return NaN
                     with m.If((b_e == 128) & (a_s != b_s)):
-                        m.d.sync += [
-                          z[31].eq(b_s),    # sign: b_s
-                          z[23:31].eq(255), # exp: 0b11111...
-                          z[22].eq(1),      # mantissa top bit: 1
-                          z[0:22].eq(0)     # mantissa rest: 0b0000...
-                        ]
+                        m.d.sync += self.create_z(z, b_s, 255, 1<<22)
+
                 # if b is inf return inf
                 with m.Elif(b_e == 128):
                     m.next = "put_z"
-                    m.d.sync += [
-                        z[31].eq(b_s),    # sign: b_s
-                        z[23:31].eq(255), # exp: 0b11111...
-                        z[0:23].eq(0)     # mantissa rest: 0b0000...
-                    ]
+                    m.d.sync += self.create_z(z, b_s, 255, 0)
 
                 # if a is zero and b zero return signed-a/b
                 with m.Elif(((a_e == -127) & (a_m == 0)) & \
                             ((b_e == -127) & (b_m == 0))):
                     m.next = "put_z"
-                    m.d.sync += [
-                        z[31].eq(a_s & b_s),         # sign: a/b_s
-                        z[23:31].eq(b_e[0:8] + 127), # exp: b_e (plus bias)
-                        z[0:23].eq(b_m[3:26])        # mantissa: b_m top bits
-                    ]
+                    m.d.sync += self.create_z(z, a_s & b_s,
+                                                 b_e[0:8] + 127,
+                                                 b_m[3:26])
 
                 # if a is zero return b
                 with m.Elif((a_e == -127) & (a_m == 0)):
                     m.next = "put_z"
-                    m.d.sync += [
-                        z[31].eq(b_s),               # sign: a/b_s
-                        z[23:31].eq(b_e[0:8] + 127), # exp: b_e (plus bias)
-                        z[0:23].eq(b_m[3:26])        # mantissa: b_m top bits
-                    ]
+                    m.d.sync += self.create_z(z, b_s,
+                                                 b_e[0:8] + 127,
+                                                 b_m[3:26])
 
                 # if b is zero return a
                 with m.Elif((b_e == -127) & (b_m == 0)):
                     m.next = "put_z"
-                    m.d.sync += [
-                        z[31].eq(a_s),               # sign: a/b_s
-                        z[23:31].eq(a_e[0:8] + 127), # exp: a_e (plus bias)
-                        z[0:23].eq(a_m[3:26])        # mantissa: a_m top bits
-                    ]
+                    m.d.sync += self.create_z(z, a_s,
+                                                 a_e[0:8] + 127,
+                                                 a_m[3:26])
 
                 # Denormalised Number checks
                 with m.Else():
@@ -232,21 +216,24 @@ class FPADD:
                         z_s.eq(b_s)
                 ]
 
+            # ******
+            # Second stage of add: preparation for normalisation
+
             with m.State("add_1"):
                 m.next = "normalise_1"
-
+                # tot[27] gets set when the sum overflows. shift result down
                 with m.If(tot[27]):
                     m.d.sync += [
-                        z_m.eq(tot[4:27]),
+                        z_m.eq(tot[4:28]),
                         guard.eq(tot[3]),
                         round_bit.eq(tot[2]),
                         sticky.eq(tot[1] | tot[0]),
                         z_e.eq(z_e + 1)
                 ]
-
+                # tot[27] zero case
                 with m.Else():
                     m.d.sync += [
-                        z_m.eq(tot[3:26]),
+                        z_m.eq(tot[3:27]),
                         guard.eq(tot[2]),
                         round_bit.eq(tot[1]),
                         sticky.eq(tot[0])