From: Michael Nolan Date: Sun, 10 May 2020 20:05:23 +0000 (-0400) Subject: Implement rlwinm in alu X-Git-Tag: div_pipeline~1296 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bd82f89ccad51f1fdb6f259503f6582117a23927;p=soc.git Implement rlwinm in alu --- diff --git a/src/soc/alu/alu_input_record.py b/src/soc/alu/alu_input_record.py index 0ce965b5..2c3dcc48 100644 --- a/src/soc/alu/alu_input_record.py +++ b/src/soc/alu/alu_input_record.py @@ -29,6 +29,7 @@ class CompALUOpSubset(Record): ('is_32bit', 1), ('is_signed', 1), ('data_len', 4), # TODO: should be in separate CompLDSTSubset + ('insn', 32), ('byte_reverse', 1), ('sign_extend', 1)) diff --git a/src/soc/alu/main_stage.py b/src/soc/alu/main_stage.py index 6d4bf780..173ca78f 100644 --- a/src/soc/alu/main_stage.py +++ b/src/soc/alu/main_stage.py @@ -11,10 +11,15 @@ from soc.decoder.power_enums import InternalOp from soc.alu.maskgen import MaskGen from soc.alu.rotl import ROTL +from soc.decoder.power_fields import DecodeFields +from soc.decoder.power_fieldsn import SignalBitRange + class ALUMainStage(PipeModBase): def __init__(self, pspec): super().__init__(pspec, "main") + self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn]) + self.fields.create_specs() def ispec(self): return ALUInputData(self.pspec) @@ -26,6 +31,13 @@ class ALUMainStage(PipeModBase): m = Module() comb = m.d.comb + + fields = self.fields.instrs['M'] + mb = Signal(fields['MB'][0:-1].shape()) + comb += mb.eq(fields['MB'][0:-1]) + me = Signal(fields['ME'][0:-1].shape()) + comb += me.eq(fields['ME'][0:-1]) + # check if op is 32-bit, and get sign bit from operand a is_32bit = Signal(reset_less=True) sign_bit = Signal(reset_less=True) @@ -121,6 +133,14 @@ class ALUMainStage(PipeModBase): with m.Else(): comb += self.o.o.eq(rotl_out & mask) + with m.Case(InternalOp.OP_RLC): + comb += rotate_amt.eq(self.i.b[0:5]) + comb += maskgen.mb.eq(mb+32) + comb += maskgen.me.eq(me+32) + comb += mask.eq(maskgen.o) + comb += self.o.o.eq(rotl_out & mask) + + ###### sticky overflow and context, both pass-through ##### comb += self.o.so.eq(self.i.so) diff --git a/src/soc/alu/test/test_pipe_caller.py b/src/soc/alu/test/test_pipe_caller.py index 9fff62c9..04363ab8 100644 --- a/src/soc/alu/test/test_pipe_caller.py +++ b/src/soc/alu/test/test_pipe_caller.py @@ -76,6 +76,7 @@ class ALUTestCase(FHDLTestCase): vld = yield alu.n.valid_o yield alu_out = yield alu.n.data_o.o + print(f"expected {simulator.gpr(3).value:x}, actual: {alu_out:x}") self.assertEqual(simulator.gpr(3).value, alu_out) sim.add_sync_process(process) @@ -145,6 +146,17 @@ class ALUTestCase(FHDLTestCase): with Program(lst) as program: sim = self.run_tst_program(program, initial_regs) + def test_rlwinm(self): + for i in range(10): + mb = random.randint(0,31) + me = random.randint(0,31) + sh = random.randint(0,31) + lst = [f"rlwinm 3, 1, {mb}, {me}, {sh}"] + initial_regs = [0] * 32 + initial_regs[1] = random.randint(0, (1<<64)-1) + with Program(lst) as program: + sim = self.run_tst_program(program, initial_regs) + def test_ilang(self): rec = CompALUOpSubset()