From: Luke Kenneth Casson Leighton Date: Wed, 1 Jul 2020 11:21:46 +0000 (+0100) Subject: start running trap unit test, fixing errors X-Git-Tag: div_pipeline~192 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=022c968392e979c6d8408600869a89bbf605aabb;p=soc.git start running trap unit test, fixing errors --- diff --git a/src/soc/fu/test/common.py b/src/soc/fu/test/common.py index f663efe1..b526cc33 100644 --- a/src/soc/fu/test/common.py +++ b/src/soc/fu/test/common.py @@ -3,8 +3,9 @@ Bugreports: * https://bugs.libre-soc.org/show_bug.cgi?id=361 """ -from soc.decoder.power_enums import XER_bits, CryIn +from soc.decoder.power_enums import XER_bits, CryIn, spr_dict from soc.regfile.util import fast_reg_to_spr # HACK! +from soc.regfile.regfiles import FastRegs class TestCase: @@ -28,6 +29,17 @@ class TestCase: class ALUHelpers: + def get_sim_fast_reg(res, sim, dec2, reg, name): + spr_sel = fast_reg_to_spr(reg) + spr_data = sim.spr[spr_sel].value + res[name] = spr_data + + def get_sim_cia(res, sim, dec2): + return self.get_sim_fast_reg(res, sim, dec2, FastRegs.PC, 'pc') + + def get_sim_msr(res, sim, dec2): + return self.get_sim_fast_reg(res, sim, dec2, FastRegs.MSR, 'msr') + def get_sim_fast_spr1(res, sim, dec2): fast1_en = yield dec2.e.read_fast1.ok if fast1_en: @@ -110,6 +122,10 @@ class ALUHelpers: print ("extra inputs: so", so) yield alu.p.data_i.xer_so.eq(so) + def set_fast_msr(alu, dec2, inp): + if 'msr' in inp: + yield alu.p.data_i.msr.eq(inp['msr']) + def set_fast_cia(alu, dec2, inp): if 'cia' in inp: yield alu.p.data_i.cia.eq(inp['cia']) @@ -140,6 +156,26 @@ class ALUHelpers: else: yield alu.p.data_i.full_cr.eq(0) + def get_fast_spr1(res, alu, dec2): + spr1_valid = yield alu.n.data_o.spr1.ok + if spr1_valid: + res['spr1'] = yield alu.n.data_o.spr1.data + + def get_fast_spr2(res, alu, dec2): + spr2_valid = yield alu.n.data_o.spr2.ok + if spr2_valid: + res['spr2'] = yield alu.n.data_o.spr2.data + + def get_fast_nia(res, alu, dec2): + nia_valid = yield alu.n.data_o.nia.ok + if nia_valid: + res['nia'] = yield alu.n.data_o.nia.data + + def get_fast_msr(res, alu, dec2): + msr_valid = yield alu.n.data_o.msr.ok + if msr_valid: + res['msr'] = yield alu.n.data_o.msr.data + def get_int_o1(res, alu, dec2): out_reg_valid = yield dec2.e.write_ea.ok if out_reg_valid: @@ -190,6 +226,20 @@ class ALUHelpers: cridx = yield dec2.e.write_cr.data res['cr_a'] = sim.crl[cridx].get_range().value + def get_wr_fast_spr2(res, sim, dec2): + ok = yield dec2.e.write_fast2.ok + if ok: + spr_num = yield dec2.e.write_fast2.data + spr_name = spr_dict[spr_num] + res['spr2'] = sim.spr[spr_name] + + def get_wr_fast_spr1(res, sim, dec2): + ok = yield dec2.e.write_fast1.ok + if ok: + spr_num = yield dec2.e.write_fast1.data + spr_name = spr_dict[spr_num] + res['spr1'] = sim.spr[spr_name] + def get_wr_sim_xer_ca(res, sim, dec2): cry_out = yield dec2.e.output_carry if cry_out: diff --git a/src/soc/fu/trap/main_stage.py b/src/soc/fu/trap/main_stage.py index 222da5dd..aac93838 100644 --- a/src/soc/fu/trap/main_stage.py +++ b/src/soc/fu/trap/main_stage.py @@ -87,6 +87,7 @@ class TrapMainStage(PipeModBase): def trap(self, m, return_addr, trap_addr): """trap """ # TODO add descriptive docstring comb = m.d.comb + msr_i = self.i.msr nia_o, srr0_o, srr1_o = self.o.nia, self.o.srr0, self.o.srr1 # trap address @@ -172,7 +173,7 @@ class TrapMainStage(PipeModBase): # trap instructions (tw, twi, td, tdi) with m.If(should_trap): # generate trap-type program interrupt - self.trap(trapaddr<<4, cia_i) + self.trap(m, trapaddr<<4, cia_i) with m.If(traptype == 0): # say trap occurred (see 3.0B Book III 7.5.9) comb += srr1_o.data[PI_TRAP].eq(1) @@ -181,7 +182,7 @@ class TrapMainStage(PipeModBase): with m.If(traptype & TT_FP): comb += srr1_o.data[PI_FP].eq(1) with m.If(traptype & TT_ADDR): - comb += srr1_o.data[PI_ADDR].eq(1) + comb += srr1_o.data[PI_ADR].eq(1) # move to MSR with m.Case(InternalOp.OP_MTMSR): @@ -221,7 +222,7 @@ class TrapMainStage(PipeModBase): # the decoder's job, not ours, here. # jump to the trap address, return at cia+4 - self.trap(0xc00, cia_i+4) + self.trap(m, 0xc00, cia_i+4) # TODO (later) #with m.Case(InternalOp.OP_ADDPCIS): diff --git a/src/soc/fu/trap/pipe_data.py b/src/soc/fu/trap/pipe_data.py index 6819fb4f..99fe0709 100644 --- a/src/soc/fu/trap/pipe_data.py +++ b/src/soc/fu/trap/pipe_data.py @@ -1,5 +1,5 @@ -from soc.fu.pipe_data import IntegerData -from soc.fu.alu.alu_input_record import CompALUOpSubset # TODO: replace +from soc.fu.pipe_data import IntegerData, CommonPipeSpec +from soc.fu.trap.trap_input_record import CompTrapOpSubset class TrapInputData(IntegerData): @@ -28,6 +28,6 @@ class TrapOutputData(IntegerData): # TODO: replace CompALUOpSubset with CompTrapOpSubset -class TrapPipeSpec: +class TrapPipeSpec(CommonPipeSpec): regspec = (TrapInputData.regspec, TrapOutputData.regspec) - opsubsetkls = CompALUOpSubset + opsubsetkls = CompTrapOpSubset diff --git a/src/soc/fu/trap/pipeline.py b/src/soc/fu/trap/pipeline.py new file mode 100644 index 00000000..1fa867b5 --- /dev/null +++ b/src/soc/fu/trap/pipeline.py @@ -0,0 +1,22 @@ +from nmutil.singlepipe import ControlBase +from nmutil.pipemodbase import PipeModBaseChain +from soc.fu.trap.main_stage import TrapMainStage + +class TrapStages(PipeModBaseChain): + def get_chain(self): + main = TrapMainStage(self.pspec) + return [main] + + +class TrapBasePipe(ControlBase): + def __init__(self, pspec): + ControlBase.__init__(self) + self.pspec = pspec + self.pipe1 = TrapStages(pspec) + self._eqs = self.connect([self.pipe1]) + + def elaborate(self, platform): + m = ControlBase.elaborate(self, platform) + m.submodules.pipe = self.pipe1 + m.d.comb += self._eqs + return m diff --git a/src/soc/fu/trap/test/test_pipe_caller.py b/src/soc/fu/trap/test/test_pipe_caller.py index 82dc4573..9c351643 100644 --- a/src/soc/fu/trap/test/test_pipe_caller.py +++ b/src/soc/fu/trap/test/test_pipe_caller.py @@ -6,18 +6,47 @@ import unittest from soc.decoder.isa.caller import ISACaller, special_sprs from soc.decoder.power_decoder import (create_pdecode) from soc.decoder.power_decoder2 import (PowerDecode2) -from soc.decoder.power_enums import (XER_bits, Function) +from soc.decoder.power_enums import (XER_bits, Function, InternalOp, CryIn) from soc.decoder.selectable_int import SelectableInt from soc.simulator.program import Program from soc.decoder.isa.all import ISA -from soc.fu.test.common import TestCase -#from soc.fu.cr.pipeline import CRBasePipe -#from soc.fu.cr.pipe_data import CRPipeSpec +from soc.fu.test.common import (TestCase, ALUHelpers) +from soc.fu.trap.pipeline import TrapBasePipe +from soc.fu.trap.pipe_data import TrapPipeSpec import random +def get_cu_inputs(dec2, sim): + """naming (res) must conform to TrapFunctionUnit input regspec + """ + res = {} + + yield from ALUHelpers.get_sim_int_ra(res, sim, dec2) # RA + yield from ALUHelpers.get_sim_int_rb(res, sim, dec2) # RB + yield from ALUHelpers.get_sim_fast_spr1(res, sim, dec2) # SPR1 + yield from ALUHelpers.get_sim_cia(res, sim, dec2) # PC + yield from ALUHelpers.get_sim_msr(res, sim, dec2) # MSR + + print ("alu get_cu_inputs", res) + + return res + + + +def set_alu_inputs(alu, 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 + + inp = yield from get_cu_inputs(dec2, sim) + yield from ALUHelpers.set_int_ra(alu, dec2, inp) + yield from ALUHelpers.set_int_rb(alu, dec2, inp) + + yield from ALUHelpers.set_fast_cia(alu, dec2, inp) + yield from ALUHelpers.set_fast_msr(alu, dec2, inp) + # This test bench is a bit different than is usual. Initially when I # was writing it, I had all of the tests call a function to create a @@ -26,7 +55,7 @@ import random # should have. However, this was really slow, since it needed to # create and tear down the dut and simulator for every test case. -# Now, instead of doing that, every test case in ALUTestCase puts some +# Now, instead of doing that, every test case in TrapTestCase puts some # data into the test_data list below, describing the instructions to # be tested and the initial state. Once all the tests have been run, # test_data gets passed to TestRunner which then sets up the DUT and @@ -40,91 +69,110 @@ import random class TrapTestCase(FHDLTestCase): test_data = [] + def __init__(self, name): super().__init__(name) self.test_name = name -# def run_tst_program(self, prog, initial_regs=None, initial_sprs=None, -# initial_cr=0): -# tc = TestCase(prog, self.test_name, -# regs=initial_regs, sprs=initial_sprs, cr=initial_cr) -# self.test_data.append(tc) -# -# def test_crop(self): -# insns = ["crand", "cror", "crnand", "crnor", "crxor", "creqv", -# "crandc", "crorc"] -# for i in range(40): -# choice = random.choice(insns) -# ba = random.randint(0, 31) -# bb = random.randint(0, 31) -# bt = random.randint(0, 31) -# lst = [f"{choice} {ba}, {bb}, {bt}"] -# cr = random.randint(0, (1<<32)-1) -# self.run_tst_program(Program(lst), initial_cr=cr) -# -# def test_crand(self): -# for i in range(20): -# lst = ["crand 0, 11, 13"] -# cr = random.randint(0, (1<<32)-1) -# self.run_tst_program(Program(lst), initial_cr=cr) -# -# def test_mcrf(self): -# lst = ["mcrf 5, 1"] -# cr = 0xfeff0000 -# self.run_tst_program(Program(lst), initial_cr=cr) -# -# def test_mtcrf(self): -# for i in range(20): -# mask = random.randint(0, 255) -# lst = [f"mtcrf {mask}, 2"] -# cr = random.randint(0, (1<<32)-1) -# initial_regs = [0] * 32 -# initial_regs[2] = random.randint(0, (1<<32)-1) -# self.run_tst_program(Program(lst), initial_regs=initial_regs, -# initial_cr=cr) - - -# def get_cu_inputs(dec2, sim): -# """naming (res) must conform to CRFunctionUnit input regspec -# """ -# res = {} -# full_reg = yield dec2.e.read_cr_whole -# -# # full CR -# print(sim.cr.get_range().value) -# if full_reg: -# res['full_cr'] = sim.cr.get_range().value -# else: -# # CR A -# cr1_en = yield dec2.e.read_cr1.ok -# if cr1_en: -# cr1_sel = yield dec2.e.read_cr1.data -# res['cr_a'] = sim.crl[cr1_sel].get_range().value -# cr2_en = yield dec2.e.read_cr2.ok -# # CR B -# if cr2_en: -# cr2_sel = yield dec2.e.read_cr2.data -# res['cr_b'] = sim.crl[cr2_sel].get_range().value -# cr3_en = yield dec2.e.read_cr3.ok -# # CR C -# if cr3_en: -# cr3_sel = yield dec2.e.read_cr3.data -# res['cr_c'] = sim.crl[cr3_sel].get_range().value -# -# # RA/RC -# reg1_ok = yield dec2.e.read_reg1.ok -# if reg1_ok: -# data1 = yield dec2.e.read_reg1.data -# res['ra'] = sim.gpr(data1).value -# -# # RB (or immediate) -# reg2_ok = yield dec2.e.read_reg2.ok -# if reg2_ok: -# data2 = yield dec2.e.read_reg2.data -# res['rb'] = sim.gpr(data2).value -# -# print ("get inputs", res) -# return res + def run_tst_program(self, prog, initial_regs=None, initial_sprs=None): + tc = TestCase(prog, self.test_name, initial_regs, initial_sprs) + self.test_data.append(tc) + + def test_1_regression(self): + lst = [f"extsw 3, 1"] + initial_regs = [0] * 32 + initial_regs[1] = 0xb6a1fc6c8576af91 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"subf 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x3d7f3f7ca24bac7b + initial_regs[2] = 0xf6b2ac5e13ee15c2 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"subf 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x833652d96c7c0058 + initial_regs[2] = 0x1c27ecff8a086c1a + self.run_tst_program(Program(lst), initial_regs) + lst = [f"extsb 3, 1"] + initial_regs = [0] * 32 + initial_regs[1] = 0x7f9497aaff900ea0 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"add. 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0xc523e996a8ff6215 + initial_regs[2] = 0xe1e5b9cc9864c4a8 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"add 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x2e08ae202742baf8 + initial_regs[2] = 0x86c43ece9efe5baa + self.run_tst_program(Program(lst), initial_regs) + + def test_rand(self): + insns = ["add", "add.", "subf"] + for i in range(40): + choice = random.choice(insns) + lst = [f"{choice} 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = random.randint(0, (1<<64)-1) + initial_regs[2] = random.randint(0, (1<<64)-1) + self.run_tst_program(Program(lst), initial_regs) + + def test_rand_imm(self): + insns = ["addi", "addis", "subfic"] + for i in range(10): + choice = random.choice(insns) + imm = random.randint(-(1<<15), (1<<15)-1) + lst = [f"{choice} 3, 1, {imm}"] + print(lst) + initial_regs = [0] * 32 + initial_regs[1] = random.randint(0, (1<<64)-1) + self.run_tst_program(Program(lst), initial_regs) + + def test_0_adde(self): + lst = ["adde. 5, 6, 7"] + for i in range(10): + initial_regs = [0] * 32 + initial_regs[6] = random.randint(0, (1<<64)-1) + initial_regs[7] = random.randint(0, (1<<64)-1) + initial_sprs = {} + xer = SelectableInt(0, 64) + xer[XER_bits['CA']] = 1 + initial_sprs[special_sprs['XER']] = xer + self.run_tst_program(Program(lst), initial_regs, initial_sprs) + + def test_cmp(self): + lst = ["subf. 1, 6, 7", + "cmp cr2, 1, 6, 7"] + initial_regs = [0] * 32 + initial_regs[6] = 0x10 + initial_regs[7] = 0x05 + self.run_tst_program(Program(lst), initial_regs, {}) + + def test_extsb(self): + insns = ["extsb", "extsh", "extsw"] + for i in range(10): + choice = random.choice(insns) + lst = [f"{choice} 3, 1"] + print(lst) + initial_regs = [0] * 32 + initial_regs[1] = random.randint(0, (1<<64)-1) + self.run_tst_program(Program(lst), initial_regs) + + def test_cmpeqb(self): + lst = ["cmpeqb cr1, 1, 2"] + for i in range(20): + initial_regs = [0] * 32 + initial_regs[1] = i + initial_regs[2] = 0x0001030507090b0f + self.run_tst_program(Program(lst), initial_regs, {}) + + def test_ilang(self): + pspec = TrapPipeSpec(id_wid=2) + alu = TrapBasePipe(pspec) + vl = rtlil.convert(alu, ports=alu.ports()) + with open("alu_pipeline.il", "w") as f: + f.write(vl) class TestRunner(FHDLTestCase): @@ -132,47 +180,6 @@ class TestRunner(FHDLTestCase): super().__init__("run_all") self.test_data = test_data -# def set_inputs(self, alu, dec2, simulator): -# inp = yield from get_cu_inputs(dec2, simulator) -# if 'full_cr' in inp: -# yield alu.p.data_i.full_cr.eq(inp['full_cr']) -# else: -# yield alu.p.data_i.full_cr.eq(0) -# if 'cr_a' in inp: -# yield alu.p.data_i.cr_a.eq(inp['cr_a']) -# if 'cr_b' in inp: -# yield alu.p.data_i.cr_b.eq(inp['cr_b']) -# if 'cr_c' in inp: -# yield alu.p.data_i.cr_c.eq(inp['cr_c']) -# if 'ra' in inp: -# yield alu.p.data_i.ra.eq(inp['ra']) -# else: -# yield alu.p.data_i.ra.eq(0) -# if 'rb' in inp: -# yield alu.p.data_i.rb.eq(inp['rb']) -# else: -# yield alu.p.data_i.rb.eq(0) -# -# def assert_outputs(self, alu, dec2, simulator, code): -# whole_reg = yield dec2.e.write_cr_whole -# cr_en = yield dec2.e.write_cr.ok -# if whole_reg: -# full_cr = yield alu.n.data_o.full_cr.data -# expected_cr = simulator.cr.get_range().value -# self.assertEqual(expected_cr, full_cr, code) -# elif cr_en: -# cr_sel = yield dec2.e.write_cr.data -# expected_cr = simulator.crl[cr_sel].get_range().value -# real_cr = yield alu.n.data_o.cr.data -# self.assertEqual(expected_cr, real_cr, code) -# alu_out = yield alu.n.data_o.o.data -# out_reg_valid = yield dec2.e.write_reg.ok -# if out_reg_valid: -# write_reg_idx = yield dec2.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) - def run_all(self): m = Module() comb = m.d.comb @@ -182,11 +189,12 @@ class TestRunner(FHDLTestCase): m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode) -# pspec = CRPipeSpec(id_wid=2) -# m.submodules.alu = alu = CRBasePipe(pspec) -# -# comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.e) -# comb += alu.n.ready_i.eq(1) + pspec = TrapPipeSpec(id_wid=2) + m.submodules.alu = alu = TrapBasePipe(pspec) + + comb += alu.p.data_i.ctx.op.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) @@ -196,7 +204,8 @@ class TestRunner(FHDLTestCase): print(test.name) program = test.program self.subTest(test.name) - sim = ISA(pdecode2, test.regs, test.sprs, test.cr) + sim = ISA(pdecode2, test.regs, test.sprs, test.cr, + test.mem, test.msr) gen = program.generate_instructions() instructions = list(zip(gen, program.assembly.splitlines())) @@ -204,17 +213,21 @@ class TestRunner(FHDLTestCase): while index < len(instructions): ins, code = instructions[index] - print("0x{:X}".format(ins & 0xffffffff)) + print("instruction: 0x{:X}".format(ins & 0xffffffff)) print(code) + if 'XER' in sim.spr: + so = 1 if sim.spr['XER'][XER_bits['SO']] else 0 + ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0 + ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0 + print ("before: so/ov/32", so, ov, ov32) # ask the decoder to decode this binary data (endian'd) yield pdecode2.dec.bigendian.eq(0) # little / big? yield instruction.eq(ins) # raw binary instr. yield Settle() - yield from self.set_inputs(alu, pdecode2, sim) - yield alu.p.valid_i.eq(1) fn_unit = yield pdecode2.e.fn_unit - self.assertEqual(fn_unit, Function.CR.value, code) + self.assertEqual(fn_unit, Function.Trap.value) + yield from set_alu_inputs(alu, pdecode2, sim) yield opname = code.split(' ')[0] yield from sim.call(opname) @@ -225,13 +238,54 @@ class TestRunner(FHDLTestCase): yield vld = yield alu.n.valid_o yield - yield from self.assert_outputs(alu, pdecode2, sim, code) + + yield from self.check_alu_outputs(alu, pdecode2, sim, code) sim.add_sync_process(process) - with sim.write_vcd("simulator.vcd", "simulator.gtkw", + with sim.write_vcd("alu_simulator.vcd", "simulator.gtkw", traces=[]): sim.run() + def check_alu_outputs(self, alu, dec2, sim, code): + + rc = yield dec2.e.rc.data + cridx_ok = yield dec2.e.write_cr.ok + cridx = yield dec2.e.write_cr.data + + print ("check extra output", repr(code), cridx_ok, cridx) + if rc: + self.assertEqual(cridx, 0, code) + + oe = yield dec2.e.oe.oe + oe_ok = yield dec2.e.oe.ok + if not oe or not oe_ok: + # if OE not enabled, XER SO and OV must correspondingly be false + so_ok = yield alu.n.data_o.xer_so.ok + ov_ok = yield alu.n.data_o.xer_ov.ok + self.assertEqual(so_ok, False, code) + self.assertEqual(ov_ok, False, code) + + sim_o = {} + res = {} + + yield from ALUHelpers.get_int_o(res, alu, dec2) + yield from ALUHelpers.get_fast_spr1(res, alu, dec2) + yield from ALUHelpers.get_fast_spr2(res, alu, dec2) + yield from ALUHelpers.get_fast_nia(res, alu, dec2) + yield from ALUHelpers.get_fast_msr(res, alu, dec2) + + yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2) + yield from ALUHelpers.get_wr_sim_cr_a(sim_o, sim, dec2) + yield from ALUHelpers.get_sim_xer_ov(sim_o, sim, dec2) + yield from ALUHelpers.get_wr_sim_xer_ca(sim_o, sim, dec2) + yield from ALUHelpers.get_sim_xer_so(sim_o, sim, dec2) + + ALUHelpers.check_cr_a(self, res, sim_o, "CR%d %s" % (cridx, code)) + ALUHelpers.check_xer_ov(self, res, sim_o, code) + ALUHelpers.check_xer_ca(self, res, sim_o, code) + ALUHelpers.check_int_o(self, res, sim_o, code) + ALUHelpers.check_xer_so(self, res, sim_o, code) + if __name__ == "__main__": unittest.main(exit=False) diff --git a/src/soc/fu/trap/trap_input_data.py b/src/soc/fu/trap/trap_input_data.py deleted file mode 100644 index 2a03c42e..00000000 --- a/src/soc/fu/trap/trap_input_data.py +++ /dev/null @@ -1,45 +0,0 @@ -from nmigen.hdl.rec import Record, Layout - -from soc.decoder.power_enums import (InternalOp, Function) - - -class CompTrapOpSubset(Record): - """CompTrapOpSubset - - a copy of the relevant subset information from Decode2Execute1Type - needed for TRAP operations. use with eq_from_execute1 (below) to - grab subsets. - """ - def __init__(self, name=None): - layout = (('insn_type', InternalOp), - ('fn_unit', Function), - ('insn', 32), - ('traptype', 4), # see trap main_stage.py and PowerDecoder2 - ('trapaddr', 13), - ) - - Record.__init__(self, Layout(layout), name=name) - - # grrr. Record does not have kwargs - self.insn_type.reset_less = True - self.insn.reset_less = True - self.fn_unit.reset_less = True - self.traptype.reset_less = True - self.trapaddr.reset_less = True - - def eq_from_execute1(self, other): - """ use this to copy in from Decode2Execute1Type - """ - res = [] - for fname, sig in self.fields.items(): - eqfrom = other.fields[fname] - res.append(sig.eq(eqfrom)) - return res - - def ports(self): - return [self.insn_type, - self.insn, - self.fn_unit, - self.traptype, - self.trapaddr, - ] diff --git a/src/soc/fu/trap/trap_input_record.py b/src/soc/fu/trap/trap_input_record.py new file mode 100644 index 00000000..d15dca7e --- /dev/null +++ b/src/soc/fu/trap/trap_input_record.py @@ -0,0 +1,48 @@ +from nmigen.hdl.rec import Record, Layout + +from soc.decoder.power_enums import (InternalOp, Function) + + +class CompTrapOpSubset(Record): + """CompTrapOpSubset + + a copy of the relevant subset information from Decode2Execute1Type + needed for TRAP operations. use with eq_from_execute1 (below) to + grab subsets. + """ + def __init__(self, name=None): + layout = (('insn_type', InternalOp), + ('fn_unit', Function), + ('insn', 32), + ('is_32bit', 1), + ('traptype', 4), # see trap main_stage.py and PowerDecoder2 + ('trapaddr', 13), + ) + + Record.__init__(self, Layout(layout), name=name) + + # grrr. Record does not have kwargs + self.insn_type.reset_less = True + self.insn.reset_less = True + self.fn_unit.reset_less = True + self.is_32bit.reset_less = True + self.traptype.reset_less = True + self.trapaddr.reset_less = True + + def eq_from_execute1(self, other): + """ use this to copy in from Decode2Execute1Type + """ + res = [] + for fname, sig in self.fields.items(): + eqfrom = other.fields[fname] + res.append(sig.eq(eqfrom)) + return res + + def ports(self): + return [self.insn_type, + self.insn, + self.fn_unit, + self.is_32bit, + self.traptype, + self.trapaddr, + ]