From 9d37bed966d6bf49cb3a642272298337b752127e Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sun, 26 Jan 2020 15:59:15 -0500 Subject: [PATCH] FSGNJ working now in all three modes This adds the functionality of the FSIGNJ RISCV instruction, namely: When the opcode is 0x00 - it combines the sign bit of operand B with the rest of the value in operand A When the opcode is 0x01 - it combines the inverted sign bit of operand B with the rest of the value in operand A When the opcode is 0x02 - it combines the sign bit composed of the exclusive OR of the sign bits of A and B with the rest of the value in operand A This also modifies the unit test for the module to test each of these behaviors for 32 bit floats --- src/ieee754/fsgnj/fsgnj.py | 18 ++++++++++--- src/ieee754/fsgnj/pipeline.py | 4 --- src/ieee754/fsgnj/test/test_fsgnj_pipe.py | 32 +++++++++++++++++++---- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/ieee754/fsgnj/fsgnj.py b/src/ieee754/fsgnj/fsgnj.py index 4bb03734..8aef149c 100644 --- a/src/ieee754/fsgnj/fsgnj.py +++ b/src/ieee754/fsgnj/fsgnj.py @@ -38,12 +38,24 @@ class FSGNJPipeMod(PipeModBase): # decode: XXX really should move to separate stage z1 = self.o.z a = self.i.a + b = self.i.b + + opcode = self.i.ctx.op + + sign = Signal() + + with m.Switch(opcode): + with m.Case(0b00): + comb += sign.eq(b[31]) + with m.Case(0b01): + comb += sign.eq(~b[31]) + with m.Case(0b10): + comb += sign.eq(a[31] ^ b[31]) + + comb += z1.eq(Cat(a[0:31], sign)) - comb += z1.eq(a) # copy the context (muxid, operator) comb += self.o.ctx.eq(self.i.ctx) return m - - diff --git a/src/ieee754/fsgnj/pipeline.py b/src/ieee754/fsgnj/pipeline.py index f9e803fe..cf801efb 100644 --- a/src/ieee754/fsgnj/pipeline.py +++ b/src/ieee754/fsgnj/pipeline.py @@ -58,7 +58,3 @@ class FSGNJMuxInOut(ReservationStations): self.alu = FSGNJBasePipe(self.in_pspec) ReservationStations.__init__(self, num_rows) - - - - diff --git a/src/ieee754/fsgnj/test/test_fsgnj_pipe.py b/src/ieee754/fsgnj/test/test_fsgnj_pipe.py index d75d30d4..ded01e3b 100644 --- a/src/ieee754/fsgnj/test/test_fsgnj_pipe.py +++ b/src/ieee754/fsgnj/test/test_fsgnj_pipe.py @@ -13,15 +13,37 @@ from sfpy import Float64, Float32, Float16 # signed int to fp ###################### -def fsgnj_abs(x): - return x.__abs__() +def fsgnj_f32_mov(a, b): + return Float32.from_bits((a.bits & 0x7fffffff) | (b.bits & 0x80000000)) + +def fsgnj_f32_neg(a, b): + sign = b.bits & 0x80000000 + sign = sign ^ 0x80000000 + return Float32.from_bits((a.bits & 0x7fffffff) | sign) + +def fsgnj_f32_abs(a, b): + bsign = b.bits & 0x80000000 + asign = a.bits & 0x80000000 + sign = asign ^ bsign + return Float32.from_bits((a.bits & 0x7fffffff) | sign) + +def test_fsgnj_mov(): + dut = FSGNJMuxInOut(32, 4) + runfp(dut, 32, "test_fsgnj_f32_mov", Float32, fsgnj_f32_mov, + False, n_vals=10, opcode=0x0) +def test_fsgnj_neg(): + dut = FSGNJMuxInOut(32, 4) + runfp(dut, 32, "test_fsgnj_f32_neg", Float32, fsgnj_f32_neg, + False, n_vals=10, opcode=0x1) def test_fsgnj_abs(): dut = FSGNJMuxInOut(32, 4) - runfp(dut, 32, "test_fsgnj_abs", Float32, fsgnj_abs, - True, n_vals=10, opcode=0x0) + runfp(dut, 32, "test_fsgnj_f32_abs", Float32, fsgnj_f32_abs, + False, n_vals=10, opcode=0x2) if __name__ == '__main__': - for i in range(200): + for i in range(50): + test_fsgnj_mov() + test_fsgnj_neg() test_fsgnj_abs() -- 2.30.2