Handle algebraic shifts too
authorMichael Nolan <mtnolan2640@gmail.com>
Sat, 9 May 2020 17:21:07 +0000 (13:21 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Sat, 9 May 2020 17:21:07 +0000 (13:21 -0400)
src/soc/alu/main_stage.py
src/soc/alu/output_stage.py
src/soc/alu/test/test_pipe_caller.py

index e66a769e94de9a440580412f76d867caf99d0229..5385c5aad0a21c4877daec3affd39305f42ce612 100644 (file)
@@ -28,6 +28,8 @@ class ALUMainStage(PipeModBase):
 
         is_32bit = Signal(reset_less=True)
         comb += is_32bit.eq(self.i.ctx.op.is_32bit)
+        sign_bit = Signal(reset_less=True)
+        comb += sign_bit.eq(Mux(is_32bit, self.i.a[31], self.i.a[63]))
 
         add_output = Signal(self.i.a.width + 1, reset_less=True)
         comb += add_output.eq(self.i.a + self.i.b + self.i.carry_in)
@@ -92,7 +94,12 @@ class ALUMainStage(PipeModBase):
                         comb += mask.eq(0)
                     with m.Else():
                         comb += mask.eq(maskgen.o)
-                comb += self.o.o.eq(rotl_out & mask)
+                with m.If(self.i.ctx.op.is_signed):
+                    comb += self.o.o.eq(rotl_out & mask |
+                                        Mux(sign_bit, ~mask, 0))
+                    comb += self.o.carry_out.eq(sign_bit & ((rotl_out & mask) != 0))
+                with m.Else():
+                    comb += self.o.o.eq(rotl_out & mask)
 
         ###### sticky overflow and context, both pass-through #####
 
index f71c59cc7dbbafb986add122dc1ce4994b7e3e95..590612220cab31778d6590089e954c16b8bd1cd3 100644 (file)
@@ -23,16 +23,12 @@ class ALUOutputStage(PipeModBase):
         comb = m.d.comb
 
         o = Signal.like(self.i.o)
-        o2 = Signal.like(self.i.o)
         with m.If(self.i.ctx.op.invert_out):
-            comb += o2.eq(~self.i.o)
+            comb += o.eq(~self.i.o)
         with m.Else():
-            comb += o2.eq(self.i.o)
+            comb += o.eq(self.i.o)
+        
 
-        with m.If(self.i.ctx.op.is_32bit):
-            comb += o.eq(Cat(o2[0:32], Repl(0, 32)))
-        with m.Else():
-            comb += o.eq(o2)
 
         is_zero = Signal(reset_less=True)
         is_positive = Signal(reset_less=True)
index 3be8d3efaa4951fc2a1ff4d5369686b43c7b53cf..581fef1b8caca470655b8d079afc651b36c56ec2 100644 (file)
@@ -125,7 +125,7 @@ class ALUTestCase(FHDLTestCase):
                 sim = self.run_tst_program(program, initial_regs)
 
     def test_shift(self):
-        insns = ["slw", "sld", "srw", "srd"]
+        insns = ["slw", "sld", "srw", "srd", "sraw", "srad"]
         for i in range(20):
             choice = random.choice(insns)
             lst = [f"{choice} 3, 1, 2"]
@@ -136,6 +136,15 @@ class ALUTestCase(FHDLTestCase):
             with Program(lst) as program:
                 sim = self.run_tst_program(program, initial_regs)
 
+    def test_shift_arith(self):
+        lst = ["sraw 3, 1, 2"]
+        initial_regs = [0] * 32
+        initial_regs[1] = random.randint(0, (1<<64)-1)
+        initial_regs[2] = random.randint(0, 63)
+        print(initial_regs[1], initial_regs[2])
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+
     @unittest.skip("broken")
     def test_ilang(self):
         rec = CompALUOpSubset()