From 3a5da87c95ae3212fd117926651ea7ee1e3d387d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 28 May 2020 12:55:58 +0100 Subject: [PATCH] debugging test_alu_compunit.py --- src/soc/experiment/compalu_multi.py | 7 +- .../fu/compunits/test/test_alu_compunit.py | 102 +++++++++++------- src/soc/fu/regspec.py | 1 + 3 files changed, 70 insertions(+), 40 deletions(-) diff --git a/src/soc/experiment/compalu_multi.py b/src/soc/experiment/compalu_multi.py index 40374812..815ff15a 100644 --- a/src/soc/experiment/compalu_multi.py +++ b/src/soc/experiment/compalu_multi.py @@ -52,6 +52,7 @@ class CompUnitRecord(RegSpec, RecordObject): RegSpec.__init__(self, rwid, n_src, n_dst) RecordObject.__init__(self, name) self._subkls = subkls + n_src, n_dst = self._n_src, self._n_dst # create source operands src = [] @@ -101,9 +102,10 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): * :n_dst: number of destination operands """ RegSpecALUAPI.__init__(self, rwid, alu) - self.n_src, self.n_dst = n_src, n_dst self.opsubsetkls = opsubsetkls self.cu = cu = CompUnitRecord(opsubsetkls, rwid, n_src, n_dst) + n_src, n_dst = self.n_src, self.n_dst = cu._n_src, cu._n_dst + print ("n_src %d n_dst %d" % (self.n_src, self.n_dst)) # convenience names for src operands for i in range(n_src): @@ -213,7 +215,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): drl = [] for i in range(self.n_dst): name = "data_r%d" % i - data_r = Signal(self.cu._get_srcwid(i), name=name, reset_less=True) + data_r = Signal(self.cu._get_dstwid(i), name=name, reset_less=True) latchregister(m, self.get_out(i), data_r, req_l.q[i], name + "_l") drl.append(data_r) @@ -225,6 +227,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): # 2nd operand in the input "regspec". see for example # soc.fu.alu.pipe_data.ALUInputData sl = [] + print ("src_i", self.src_i) for i in range(self.n_src): sl.append([self.src_i[i], self.get_in(i), src_l.q[i], Const(1,1)]) diff --git a/src/soc/fu/compunits/test/test_alu_compunit.py b/src/soc/fu/compunits/test/test_alu_compunit.py index 0d83e4c5..c14d683f 100644 --- a/src/soc/fu/compunits/test/test_alu_compunit.py +++ b/src/soc/fu/compunits/test/test_alu_compunit.py @@ -12,11 +12,38 @@ from soc.simulator.program import Program from soc.decoder.isa.all import ISA from soc.fu.alu.test.test_pipe_caller import TestCase, ALUTestCase, test_data -from soc.fu.compunits import ALUFunctionUnit +from soc.fu.compunits.compunits import ALUFunctionUnit import random - -def set_alu_inputs(alu, dec2, sim): +def set_cu_input(cu, idx, data): + yield cu.src_i[idx].eq(data) + while True: + rd_rel_o = yield cu.rd.rel[idx] + print ("rd_rel %d wait" % idx, rd_rel_o) + if rd_rel_o: + break + yield + yield cu.rd.go[idx].eq(1) + yield + yield cu.rd.go[idx].eq(0) + + +def get_cu_output(cu, idx): + while True: + wr_relall_o = yield cu.wr.rel + wr_rel_o = yield cu.wr.rel[idx] + print ("wr_rel %d wait" % idx, hex(wr_relall_o), wr_rel_o) + if wr_rel_o: + break + yield + yield cu.wr.go[idx].eq(1) + yield + result = yield cu.dst_i[idx] + yield cu.wr.go[idx].eq(0) + return result + + +def set_cu_inputs(cu, dec2, sim): # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok)) # and place it into data_i.b @@ -33,29 +60,35 @@ def set_alu_inputs(alu, dec2, sim): else: data1 = 0 - yield alu.p.data_i.a.eq(data1) + if reg3_ok or reg1_ok: + yield from set_cu_input(cu, 0, data1) # If there's an immediate, set the B operand to that reg2_ok = yield dec2.e.read_reg2.ok - imm_ok = yield dec2.e.imm_data.imm_ok - if imm_ok: - data2 = yield dec2.e.imm_data.imm - elif reg2_ok: + if reg2_ok: data2 = yield dec2.e.read_reg2.data data2 = sim.gpr(data2).value else: data2 = 0 - yield alu.p.data_i.b.eq(data2) + + if reg2_ok: + yield from set_cu_input(cu, 1, data2) +def set_operand(cu, dec2, sim): + yield from cu.oper_i.eq_from_execute1(dec2.e) + yield cu.issue_i.eq(1) + yield + yield cu.issue_i.eq(0) + yield -def set_extra_alu_inputs(alu, dec2, sim): + +def set_extra_cu_inputs(cu, dec2, sim): carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0 - yield alu.p.data_i.xer_ca[0].eq(carry) - yield alu.p.data_i.xer_ca[1].eq(carry32) + yield from set_cu_input(cu, 2, carry | (carry32<<1)) so = 1 if sim.spr['XER'][XER_bits['SO']] else 0 - yield alu.p.data_i.xer_so.eq(so) + yield from set_cu_input(cu, 3, so) @@ -74,9 +107,6 @@ class TestRunner(FHDLTestCase): m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode) m.submodules.cu = cu = ALUFunctionUnit() - comb += cu.oper_i.eq_from_execute1(pdecode2.e) - comb += alu.p.valid_i.eq(1) - comb += alu.n.ready_i.eq(1) comb += pdecode2.dec.raw_opcode_in.eq(instruction) sim = Simulator(m) @@ -86,11 +116,11 @@ class TestRunner(FHDLTestCase): print(test.name) program = test.program self.subTest(test.name) - simulator = ISA(pdecode2, test.regs, test.sprs, 0) + sim = ISA(pdecode2, test.regs, test.sprs, 0) gen = program.generate_instructions() instructions = list(zip(gen, program.assembly.splitlines())) - index = simulator.pc.CIA.value//4 + index = sim.pc.CIA.value//4 while index < len(instructions): ins, code = instructions[index] @@ -103,55 +133,51 @@ class TestRunner(FHDLTestCase): yield Settle() fn_unit = yield pdecode2.e.fn_unit self.assertEqual(fn_unit, Function.ALU.value) - yield from set_alu_inputs(alu, pdecode2, simulator) - yield from set_extra_alu_inputs(alu, pdecode2, simulator) + yield from set_operand(cu, pdecode2, sim) + yield from set_cu_inputs(cu, pdecode2, sim) + yield from set_extra_cu_inputs(cu, pdecode2, sim) yield opname = code.split(' ')[0] - yield from simulator.call(opname) - index = simulator.pc.CIA.value//4 + yield from sim.call(opname) + index = sim.pc.CIA.value//4 - vld = yield alu.n.valid_o - while not vld: - yield - vld = yield alu.n.valid_o - yield - alu_out = yield alu.n.data_o.o.data out_reg_valid = yield pdecode2.e.write_reg.ok if out_reg_valid: write_reg_idx = yield pdecode2.e.write_reg.data - expected = simulator.gpr(write_reg_idx).value - print(f"expected {expected:x}, actual: {alu_out:x}") - self.assertEqual(expected, alu_out, code) - yield from self.check_extra_alu_outputs(alu, pdecode2, - simulator, code) + expected = sim.gpr(write_reg_idx).value + cu_out = yield from get_cu_output(cu, 0) + print(f"expected {expected:x}, actual: {cu_out:x}") + self.assertEqual(expected, cu_out, code) + yield from self.check_extra_cu_outputs(cu, pdecode2, + sim, code) sim.add_sync_process(process) with sim.write_vcd("simulator.vcd", "simulator.gtkw", traces=[]): sim.run() - def check_extra_alu_outputs(self, alu, dec2, sim, code): + def check_extra_cu_outputs(self, cu, dec2, sim, code): rc = yield dec2.e.rc.data if rc: cr_expected = sim.crl[0].get_range().value - cr_actual = yield alu.n.data_o.cr0.data + cr_actual = yield cu.n.data_o.cr0.data self.assertEqual(cr_expected, cr_actual, code) op = yield dec2.e.insn_type if op == InternalOp.OP_CMP.value or \ op == InternalOp.OP_CMPEQB.value: bf = yield dec2.dec.BF - cr_actual = yield alu.n.data_o.cr0.data + cr_actual = yield cu.n.data_o.cr0.data cr_expected = sim.crl[bf].get_range().value self.assertEqual(cr_expected, cr_actual, code) cry_out = yield dec2.e.output_carry if cry_out: expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 - real_carry = yield alu.n.data_o.xer_ca.data[0] # XXX CO not CO32 + real_carry = yield cu.n.data_o.xer_ca.data[0] # XXX CO not CO32 self.assertEqual(expected_carry, real_carry, code) expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0 - real_carry32 = yield alu.n.data_o.xer_ca.data[1] # XXX CO32 + real_carry32 = yield cu.n.data_o.xer_ca.data[1] # XXX CO32 self.assertEqual(expected_carry32, real_carry32, code) diff --git a/src/soc/fu/regspec.py b/src/soc/fu/regspec.py index 009f1fbc..e7a4cf8e 100644 --- a/src/soc/fu/regspec.py +++ b/src/soc/fu/regspec.py @@ -19,6 +19,7 @@ which MultiCompUnit port, how wide the connection is, and so on. def get_regspec_bitwidth(regspec, srcdest, idx): + print ("get_regspec_bitwidth", regspec, srcdest, idx) bitspec = regspec[srcdest][idx] wid = 0 print (bitspec) -- 2.30.2