From: Michael Nolan Date: Sat, 9 May 2020 17:21:07 +0000 (-0400) Subject: Handle algebraic shifts too X-Git-Tag: div_pipeline~1305 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=80e19fd89f59831d6ae775290279ecb4670d1854;p=soc.git Handle algebraic shifts too --- diff --git a/src/soc/alu/main_stage.py b/src/soc/alu/main_stage.py index e66a769e..5385c5aa 100644 --- a/src/soc/alu/main_stage.py +++ b/src/soc/alu/main_stage.py @@ -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 ##### diff --git a/src/soc/alu/output_stage.py b/src/soc/alu/output_stage.py index f71c59cc..59061222 100644 --- a/src/soc/alu/output_stage.py +++ b/src/soc/alu/output_stage.py @@ -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) diff --git a/src/soc/alu/test/test_pipe_caller.py b/src/soc/alu/test/test_pipe_caller.py index 3be8d3ef..581fef1b 100644 --- a/src/soc/alu/test/test_pipe_caller.py +++ b/src/soc/alu/test/test_pipe_caller.py @@ -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()