code-morph on add special-cases
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 25 Aug 2019 12:43:26 +0000 (13:43 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 25 Aug 2019 12:43:26 +0000 (13:43 +0100)
src/ieee754/fpadd/specialcases.py

index 106d004b53b4294897c43b2d665626f8bd176ad9..3463d993f1385e55511e0e140dd09576403c23ef 100644 (file)
@@ -51,6 +51,7 @@ class FPAddSpecialCasesMod(PipeModBase):
         e_match = Signal(reset_less=True)
         aeqmb = Signal(reset_less=True)
         abz = Signal(reset_less=True)
+        absa = Signal(reset_less=True)
         abnan = Signal(reset_less=True)
         bexp128s = Signal(reset_less=True)
 
@@ -59,48 +60,59 @@ class FPAddSpecialCasesMod(PipeModBase):
         comb += e_match.eq(a1.e == b1.e)
         comb += aeqmb.eq(s_nomatch & m_match & e_match)
         comb += abz.eq(a1.is_zero & b1.is_zero)
+        comb += absa.eq(a1.s & b1.s)
         comb += abnan.eq(a1.is_nan | b1.is_nan)
         comb += bexp128s.eq(b1.exp_128 & s_nomatch)
 
+        # prepare inf/zero/nans
+        z_zero = FPNumBaseRecord(width, False, name="z_zero")
+        z_nan = FPNumBaseRecord(width, False, name="z_nan")
+        z_infa = FPNumBaseRecord(width, False, name="z_infa")
+        z_infb = FPNumBaseRecord(width, False, name="z_infb")
+        comb += z_zero.zero(0)
+        comb += z_nan.nan(0)
+        comb += z_infa.inf(a1.s)
+        comb += z_infb.inf(b1.s)
+
         # default bypass
         comb += self.o.out_do_z.eq(1)
 
         # if a is NaN or b is NaN return NaN
         with m.If(abnan):
-            comb += self.o.z.nan(0)
+            comb += self.o.oz.eq(z_nan.v)
 
         # if a is inf return inf (or NaN)
         with m.Elif(a1.is_inf):
-            comb += self.o.z.inf(a1.s)
+            comb += self.o.oz.eq(z_infa.v)
             # if a is inf and signs don't match return NaN
             with m.If(bexp128s):
-                comb += self.o.z.nan(0)
+                comb += self.o.oz.eq(z_nan.v)
 
         # if b is inf return inf
         with m.Elif(b1.is_inf):
-            comb += self.o.z.inf(b1.s)
+            comb += self.o.oz.eq(z_infb.v)
 
         # if a is zero and b zero return signed-a/b
         with m.Elif(abz):
-            comb += self.o.z.create(a1.s & b1.s, b1.e, b1.m[3:-1])
+            comb += self.o.oz.eq(self.i.b)
+            comb += self.o.oz[-1].eq(absa)
 
         # if a is zero return b
         with m.Elif(a1.is_zero):
-            comb += self.o.z.create(b1.s, b1.e, b1.m[3:-1])
+            comb += self.o.oz.eq(b1.v)
 
         # if b is zero return a
         with m.Elif(b1.is_zero):
-            comb += self.o.z.create(a1.s, a1.e, a1.m[3:-1])
+            comb += self.o.oz.eq(a1.v)
 
         # if a equal to -b return zero (+ve zero)
         with m.Elif(aeqmb):
-            comb += self.o.z.zero(0)
+            comb += self.o.oz.eq(z_zero.v)
 
         # Denormalised Number checks next, so pass a/b data through
         with m.Else():
             comb += self.o.out_do_z.eq(0)
 
-        comb += self.o.oz.eq(self.o.z.v)
         comb += self.o.ctx.eq(self.i.ctx)
 
         return m