From 2352155642c82227e24e8782c6de61601938aa56 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sun, 26 Jan 2020 21:11:23 -0500 Subject: [PATCH] Expand FSGNJ module to 16 and 64 bit floats 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 | 12 ++- src/ieee754/fsgnj/test/test_fsgnj_pipe.py | 97 ++++++++++++++++++++--- 2 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/ieee754/fsgnj/fsgnj.py b/src/ieee754/fsgnj/fsgnj.py index 66218191..c43e180c 100644 --- a/src/ieee754/fsgnj/fsgnj.py +++ b/src/ieee754/fsgnj/fsgnj.py @@ -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) diff --git a/src/ieee754/fsgnj/test/test_fsgnj_pipe.py b/src/ieee754/fsgnj/test/test_fsgnj_pipe.py index a465c9da..2be52813 100644 --- a/src/ieee754/fsgnj/test/test_fsgnj_pipe.py +++ b/src/ieee754/fsgnj/test/test_fsgnj_pipe.py @@ -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() -- 2.30.2