Expand FSGNJ module to 16 and 64 bit floats
authorMichael Nolan <mtnolan2640@gmail.com>
Mon, 27 Jan 2020 02:11:23 +0000 (21:11 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 27 Jan 2020 02:28:53 +0000 (21:28 -0500)
This modifies fsignj.py to be compliant with other Float widths
besides 32 bit. It also modifies the unit tests to include tests for
16 and 64 bit floats

src/ieee754/fsgnj/fsgnj.py
src/ieee754/fsgnj/test/test_fsgnj_pipe.py

index 662181912ff3d2738857cc3d6d8821228619521a..c43e180c0c55d6e12ee081a5b6e236aad6a1e554 100644 (file)
@@ -28,6 +28,8 @@ class FSGNJPipeMod(PipeModBase):
 
     def elaborate(self, platform):
         m = Module()
+
+        width = self.pspec.width
         comb = m.d.comb
 
         z1 = self.o.z
@@ -40,13 +42,15 @@ class FSGNJPipeMod(PipeModBase):
 
         with m.Switch(opcode):
             with m.Case(0b00):
-                comb += sign.eq(b[31])
+                comb += sign.eq(b[-1])
             with m.Case(0b01):
-                comb += sign.eq(~b[31])
+                comb += sign.eq(~b[-1])
             with m.Case(0b10):
-                comb += sign.eq(a[31] ^ b[31])
+                comb += sign.eq(a[-1] ^ b[-1])
+            with m.Default():
+                comb += sign.eq(b[-1])
 
-        comb += z1.eq(Cat(a[0:31], sign))
+        comb += z1.eq(Cat(a[0:width-1], sign))
 
         # copy the context (muxid, operator)
         comb += self.o.ctx.eq(self.i.ctx)
index a465c9dad1440dbb83f21f64d04345566600b391..2be5281374f29afbaf565fb03ad7269047e966bd 100644 (file)
@@ -4,7 +4,7 @@
 from ieee754.fsgnj.pipeline import (FSGNJMuxInOut)
 from ieee754.fpcommon.test.fpmux import runfp
 
-from sfpy import Float32
+from sfpy import Float16, Float32, Float64
 
 
 def fsgnj_f32_mov(a, b):
@@ -24,26 +24,103 @@ def fsgnj_f32_abs(a, b):
     return Float32.from_bits((a.bits & 0x7fffffff) | sign)
 
 
-def test_fsgnj_mov():
+def fsgnj_f16_mov(a, b):
+    return Float16.from_bits((a.bits & 0x7fff) | (b.bits & 0x8000))
+
+
+def fsgnj_f16_neg(a, b):
+    sign = b.bits & 0x8000
+    sign = sign ^ 0x8000
+    return Float16.from_bits((a.bits & 0x7fff) | sign)
+
+
+def fsgnj_f16_abs(a, b):
+    bsign = b.bits & 0x8000
+    asign = a.bits & 0x8000
+    sign = asign ^ bsign
+    return Float16.from_bits((a.bits & 0x7fff) | sign)
+
+
+def fsgnj_f64_mov(a, b):
+    return Float64.from_bits((a.bits & 0x7fffffffffffffff) |
+                             (b.bits & 0x8000000000000000))
+
+
+def fsgnj_f64_neg(a, b):
+    sign = b.bits & 0x8000000000000000
+    sign = sign ^ 0x8000000000000000
+    return Float64.from_bits((a.bits & 0x7fffffffffffffff) | sign)
+
+
+def fsgnj_f64_abs(a, b):
+    bsign = b.bits & 0x8000000000000000
+    asign = a.bits & 0x8000000000000000
+    sign = asign ^ bsign
+    return Float64.from_bits((a.bits & 0x7fffffffffffffff) | sign)
+
+
+def test_fsgnj_f32_mov():
     dut = FSGNJMuxInOut(32, 4)
     runfp(dut, 32, "test_fsgnj_f32_mov", Float32, fsgnj_f32_mov,
-          n_vals=10, opcode=0x0)
+          n_vals=100, opcode=0x0)
 
 
-def test_fsgnj_neg():
+def test_fsgnj_f32_neg():
     dut = FSGNJMuxInOut(32, 4)
     runfp(dut, 32, "test_fsgnj_f32_neg", Float32, fsgnj_f32_neg,
-          n_vals=10, opcode=0x1)
+          n_vals=100, opcode=0x1)
 
 
-def test_fsgnj_abs():
+def test_fsgnj_f32_abs():
     dut = FSGNJMuxInOut(32, 4)
     runfp(dut, 32, "test_fsgnj_f32_abs", Float32, fsgnj_f32_abs,
-          n_vals=10, opcode=0x2)
+          n_vals=100, opcode=0x2)
+
+
+def test_fsgnj_f16_mov():
+    dut = FSGNJMuxInOut(16, 4)
+    runfp(dut, 16, "test_fsgnj_f16_mov", Float16, fsgnj_f16_mov,
+          n_vals=100, opcode=0x0)
+
+
+def test_fsgnj_f16_neg():
+    dut = FSGNJMuxInOut(16, 4)
+    runfp(dut, 16, "test_fsgnj_f16_neg", Float16, fsgnj_f16_neg,
+          n_vals=100, opcode=0x1)
+
+
+def test_fsgnj_f16_abs():
+    dut = FSGNJMuxInOut(16, 4)
+    runfp(dut, 16, "test_fsgnj_f16_abs", Float16, fsgnj_f16_abs,
+          n_vals=100, opcode=0x2)
+
+
+def test_fsgnj_f64_mov():
+    dut = FSGNJMuxInOut(64, 4)
+    runfp(dut, 64, "test_fsgnj_f64_mov", Float64, fsgnj_f64_mov,
+          n_vals=100, opcode=0x0)
+
+
+def test_fsgnj_f64_neg():
+    dut = FSGNJMuxInOut(64, 4)
+    runfp(dut, 64, "test_fsgnj_f64_neg", Float64, fsgnj_f64_neg,
+          n_vals=100, opcode=0x1)
+
+
+def test_fsgnj_f64_abs():
+    dut = FSGNJMuxInOut(64, 4)
+    runfp(dut, 64, "test_fsgnj_f64_abs", Float64, fsgnj_f64_abs,
+          n_vals=100, opcode=0x2)
 
 
 if __name__ == '__main__':
     for i in range(50):
-        test_fsgnj_mov()
-        test_fsgnj_neg()
-        test_fsgnj_abs()
+        test_fsgnj_f32_mov()
+        test_fsgnj_f32_neg()
+        test_fsgnj_f32_abs()
+        test_fsgnj_f16_mov()
+        test_fsgnj_f16_neg()
+        test_fsgnj_f16_abs()
+        test_fsgnj_f64_mov()
+        test_fsgnj_f64_neg()
+        test_fsgnj_f64_abs()