FSGNJ working now in all three modes
authorMichael Nolan <mtnolan2640@gmail.com>
Sun, 26 Jan 2020 20:59:15 +0000 (15:59 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 27 Jan 2020 02:28:53 +0000 (21:28 -0500)
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
src/ieee754/fsgnj/pipeline.py
src/ieee754/fsgnj/test/test_fsgnj_pipe.py

index 4bb037345e9ca5ce203d45a5afb5047bac28ad02..8aef149cfb319b6f309c73b72378b69deb51c0d8 100644 (file)
@@ -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
-
-
index f9e803fed4e69cec05693d0907b2103e6392196b..cf801efb4c13eafc6e37c0bcbf28983842d2d562 100644 (file)
@@ -58,7 +58,3 @@ class FSGNJMuxInOut(ReservationStations):
 
         self.alu = FSGNJBasePipe(self.in_pspec)
         ReservationStations.__init__(self, num_rows)
-
-
-
-
index d75d30d4022f2880063ada6b62c5432f56e3a656..ded01e3b3be8b9094c1e148cbade4adb68e289fe 100644 (file)
@@ -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()