From 79aa7f01e6acfe2ab8e7a954fd0c3e68f1430428 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Thu, 19 Mar 2020 14:08:29 -0400 Subject: [PATCH] Add tests for register+immediate ops Fix issue with decoder where a signed shifted immediate wasn't shifted by the right amount --- src/soc/decoder/power_decoder2.py | 4 +- src/soc/decoder/test/test_decoder_gas.py | 58 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 8af57933..3d5c8c6d 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -107,10 +107,10 @@ class DecodeB(Elaboratable): comb += self.imm_out.data.eq(self.dec.SI[0:-1]) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_UI_HI): - comb += self.imm_out.data.eq(self.dec.UI[0:-1]<<4) + comb += self.imm_out.data.eq(self.dec.UI[0:-1]<<16) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_SI_HI): # TODO: sign-extend here? - comb += self.imm_out.data.eq(self.dec.SI[0:-1]<<4) + comb += self.imm_out.data.eq(self.dec.SI[0:-1]<<16) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_LI): comb += self.imm_out.data.eq(self.dec.LI[0:-1]<<2) diff --git a/src/soc/decoder/test/test_decoder_gas.py b/src/soc/decoder/test/test_decoder_gas.py index b5c3eed3..13461f14 100644 --- a/src/soc/decoder/test/test_decoder_gas.py +++ b/src/soc/decoder/test/test_decoder_gas.py @@ -39,14 +39,14 @@ class RegRegOp: self.r3.num) return string - def check(self, pdecode2): + def check_results(self, pdecode2): r1sel = yield pdecode2.e.write_reg.data r3sel = yield pdecode2.e.read_reg2.data # For some reason r2 gets decoded either in read_reg1 # or read_reg3 - form = yield pdecode2.dec.op.form - if form == Form.X.value: + out_sel = yield pdecode2.dec.op.out_sel + if out_sel == OutSel.RA.value: r2sel = yield pdecode2.e.read_reg3.data else: r2sel = yield pdecode2.e.read_reg1.data @@ -58,6 +58,46 @@ class RegRegOp: assert(opc_out == self.opcode.value) +class RegImmOp: + def __init__(self): + self.ops = { + InternalOp.OP_ADD: "addi", + InternalOp.OP_ADD: "addis", + InternalOp.OP_AND: "andi.", + InternalOp.OP_OR: "ori"} + self.opcode = random.choice(list(self.ops.keys())) + self.r1 = Register(random.randrange(32)) + self.r2 = Register(random.randrange(32)) + self.imm = random.randrange(32767) + + def generate_instruction(self): + opcodestr = self.ops[self.opcode] + string = "{} {}, {}, {}\n".format(opcodestr, + self.r1.num, + self.r2.num, + self.imm) + return string + + def check_results(self, pdecode2): + print("Check") + r1sel = yield pdecode2.e.write_reg.data + # For some reason r2 gets decoded either in read_reg1 + # or read_reg3 + out_sel = yield pdecode2.dec.op.out_sel + if out_sel == OutSel.RA.value: + r2sel = yield pdecode2.e.read_reg3.data + else: + r2sel = yield pdecode2.e.read_reg1.data + assert(r1sel == self.r1.num) + assert(r2sel == self.r2.num) + + imm = yield pdecode2.e.imm_data.data + in2_sel = yield pdecode2.dec.op.in2_sel + if in2_sel in [In2Sel.CONST_SI_HI.value, In2Sel.CONST_UI_HI.value]: + assert(imm == (self.imm << 16)) + else: + assert(imm == self.imm) + class DecoderTestCase(FHDLTestCase): def get_assembled_instruction(self, instruction): @@ -78,7 +118,7 @@ class DecoderTestCase(FHDLTestCase): binary = struct.unpack('>i', binfile.read(4))[0] return binary - def run_tst(self, kls): + def run_tst(self, kls, name): random.seed(1) m = Module() comb = m.d.comb @@ -104,14 +144,18 @@ class DecoderTestCase(FHDLTestCase): yield instruction.eq(instruction_bin) yield Delay(1e-6) - checker.check(pdecode2) + yield from checker.check_results(pdecode2) sim.add_process(process) - with sim.write_vcd("gas.vcd", "gas.gtkw", traces=[pdecode2.ports()]): + with sim.write_vcd("%s.vcd" % name, "%s.gtkw" % name, + traces=[pdecode2.ports()]): sim.run() def test_reg_reg(self): - self.run_tst(RegRegOp) + self.run_tst(RegRegOp, "reg_reg") + + def test_reg_imm(self): + self.run_tst(RegImmOp, "reg_imm") if __name__ == "__main__": -- 2.30.2