add corner-cases +/-0 + NaN
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 19 Feb 2019 09:20:13 +0000 (09:20 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 19 Feb 2019 09:20:13 +0000 (09:20 +0000)
src/add/nmigen_add_experiment.py
src/add/test_add16.py

index e1d0b40c1114da2b33144825b4951ef0fca80555..6baaad66f51db6e730f9b5bf0576d3fad80267db 100644 (file)
@@ -55,10 +55,25 @@ class FPADD(FPBase):
 
             with m.State("special_cases"):
 
-                # if a is NaN or b is NaN return NaN
-                with m.If(a.is_nan() | b.is_nan()):
+                # if a is zero and b is NaN return -b
+                with m.If(a.is_zero() & (a.s==0) & b.is_nan()):
                     m.next = "put_z"
-                    m.d.sync += z.nan(1)
+                    m.d.sync += z.create(b.s, b.e, Cat(b.m[3:-2], ~b.m[0]))
+
+                # if b is zero and a is NaN return -a
+                with m.Elif(b.is_zero() & (b.s==0) & a.is_nan()):
+                    m.next = "put_z"
+                    m.d.sync += z.create(a.s, a.e, Cat(a.m[3:-2], ~a.m[0]))
+
+                # if a is -zero and b is NaN return -b
+                with m.Elif(a.is_zero() & (a.s==1) & b.is_nan()):
+                    m.next = "put_z"
+                    m.d.sync += z.create(a.s & b.s, b.e, Cat(b.m[3:-2], 1))
+
+                # if b is -zero and a is NaN return -a
+                with m.Elif(b.is_zero() & (b.s==1) & a.is_nan()):
+                    m.next = "put_z"
+                    m.d.sync += z.create(a.s & b.s, a.e, Cat(a.m[3:-2], 1))
 
                 # if a is inf return inf (or NaN)
                 with m.Elif(a.is_inf()):
index 3beccfd385e397f3380f025045f81d35f7ce4435..e45ce359b4cd5a08a8c1287c861c2f9f1827333b 100644 (file)
@@ -13,6 +13,15 @@ from unit_test_half import (get_mantissa, get_exponent, get_sign, is_nan,
                                 run_edge_cases, run_corner_cases)
 
 def testbench(dut):
+    yield from check_case(dut, 0x7800, 0xff6f, 0xff6f)
+    yield from check_case(dut, 0x0000, 0x7c32, 0x7e32)
+    yield from check_case(dut, 0x0000, 0x7da9, 0x7fa9)
+    yield from check_case(dut, 0x0000, 0x7ea0, 0x7ea0)
+    yield from check_case(dut, 0x7c9a, 0x8000, 0x7e9a)
+    yield from check_case(dut, 0x7d5e, 0x0000, 0x7f5e)
+    yield from check_case(dut, 0x8000, 0x7c8c, 0x7e8c)
+    yield from check_case(dut, 0x8000, 0xfc55, 0xfe55)
+    yield from check_case(dut, 0x8000, 0x7e1a, 0x7e1a)
     yield from check_case(dut, 0xfc00, 0x7c00, 0xfe00)
     yield from check_case(dut, 0x8000, 0, 0)
     yield from check_case(dut, 0, 0, 0)