From 8d25dfae6a9f018dc9fc805f495e836c8dee608e Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 19 Dec 2021 21:26:25 +0000 Subject: [PATCH] add hard stop address in ifetch unit test, bit of a mess: TestIssuerFSM is just being caught on the edge of attempting to execute another instruction at a TRAP point --- src/soc/simple/issuer.py | 27 +++++++++++-- src/soc/simple/test/test_issuer_mmu_ifetch.py | 39 +++++++++++++++---- src/soc/simple/test/test_runner.py | 8 +++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 156fce3c..4629c4ed 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -1227,9 +1227,22 @@ class TestIssuerInternal(TestIssuerBase): # handshake with execution FSM, move to "wait" once acknowledged with m.State("INSN_EXECUTE"): - comb += exec_insn_i_valid.eq(1) # trigger execute - with m.If(exec_insn_o_ready): # execute acknowledged us - m.next = "EXECUTE_WAIT" + if self.allow_overlap: + stopping = dbg.stopping_o + else: + stopping = Const(0) + with m.If(stopping): + # stopping: jump back to idle + m.next = "ISSUE_START" + if flush_needed: + # request the icache to stop asserting "failed" + comb += core.icache.flush_in.eq(1) + # stop instruction fault + sync += pdecode2.instr_fault.eq(0) + with m.Else(): + comb += exec_insn_i_valid.eq(1) # trigger execute + with m.If(exec_insn_o_ready): # execute acknowledged us + m.next = "EXECUTE_WAIT" with m.State("EXECUTE_WAIT"): # wait on "core stop" release, at instruction end @@ -1324,6 +1337,9 @@ class TestIssuerInternal(TestIssuerBase): comb += core.icache.flush_in.eq(1) # stop instruction fault sync += pdecode2.instr_fault.eq(0) + # if terminated return to idle + with m.If(dbg.terminate_i): + m.next = "ISSUE_START" # check if svstate needs updating: if so, write it to State Regfile with m.If(self.update_svstate): @@ -1342,6 +1358,7 @@ class TestIssuerInternal(TestIssuerBase): comb = m.d.comb sync = m.d.sync + dbg = self.dbg pdecode2 = self.pdecode2 # temporaries @@ -1394,6 +1411,10 @@ class TestIssuerInternal(TestIssuerBase): ~pdecode2.instr_fault): comb += self.insn_done.eq(1) m.next = "INSN_START" # back to fetch + # terminate returns directly to INSN_START + with m.If(dbg.terminate_i): + # comb += self.insn_done.eq(1) - no because it's not + m.next = "INSN_START" # back to fetch def elaborate(self, platform): m = super().elaborate(platform) diff --git a/src/soc/simple/test/test_issuer_mmu_ifetch.py b/src/soc/simple/test/test_issuer_mmu_ifetch.py index 5175b7cd..4d434c7f 100644 --- a/src/soc/simple/test/test_issuer_mmu_ifetch.py +++ b/src/soc/simple/test/test_issuer_mmu_ifetch.py @@ -39,34 +39,57 @@ from soc.experiment.test import pagetables class MMUTestCase(TestAccumulatorBase): - # MMUTEST: initial_msr= 16384 - # msr 16384 - # ISACaller initial_msr 16384 - # FIXME msr does not get passed to LoadStore1 - def case_5_ldst_exception(self): - lst = [#"mtspr 720,1", # mtspr PRTBL,r1 - "stb 10,0(2)", + def cse_virtual_ld_st(self): + lst = ["stb 10,0(2)", "addi 10,0, -4", "stb 10,0(5)", "lhz 6,0(2)", ] + + # set up regs initial_regs = [0] * 32 - initial_regs[1] = 0x1000000 + initial_regs[1] = 0x1000000 # hm, was going to do mtspr 720,1 with this initial_regs[2] = 0x3456 initial_regs[3] = 0x4321 initial_regs[4] = 0x6543 initial_regs[5] = 0x3457 initial_regs[10] = 0xfe + + # no pre-loaded memory here initial_mem = {} + + # set virtual and non-privileged initial_msr = 1 << MSR.PR # must set "problem" state initial_msr |= 1 << MSR.DR # set "virtual" state + + # set PRTBL to 0x1000000 initial_sprs = {720: 0x1000000} # PRTBL + print("MMUTEST: initial_msr=",initial_msr) self.add_case(Program(lst, bigendian), initial_regs, initial_mem=initial_mem, initial_sprs=initial_sprs, initial_msr=initial_msr) + def case_virtual_invalid_no_prtbl(self): + """virtual memory test but with no PRTBL set it is expected + to throw an "invalid" exception + """ + lst = ["stb 10,0(2)", + ] + + # set up regs + initial_regs = [0] * 32 + + # set virtual and non-privileged + initial_msr = 1 << MSR.PR # must set "problem" state + initial_msr |= 1 << MSR.DR # set "virtual" state + + print("MMUTEST: initial_msr=",initial_msr) + self.add_case(Program(lst, bigendian), initial_regs, + initial_msr=initial_msr, + stop_at_pc=0x400) # stop at this exception addr + if __name__ == "__main__": svp64 = True if len(sys.argv) == 2: diff --git a/src/soc/simple/test/test_runner.py b/src/soc/simple/test/test_runner.py index e83a39b7..afc24513 100644 --- a/src/soc/simple/test/test_runner.py +++ b/src/soc/simple/test/test_runner.py @@ -269,7 +269,10 @@ class HDLRunner(StateRunner): # just after the last instruction. if a load of an instruction is # requested at this address, the core is immediately put into "halt" # XXX: keep an eye out for in-order problems - yield from set_dmi(dmi, DBGCore.STOPADDR, len(instructions)*4) + hard_stop_addr = self.test.stop_at_pc + if hard_stop_addr is None: + hard_stop_addr = len(instructions)*4 + yield from set_dmi(dmi, DBGCore.STOPADDR, hard_stop_addr) # run the loop of the instructions on the current test index = (yield self.issuer.cur_state.pc) // 4 @@ -292,7 +295,8 @@ class HDLRunner(StateRunner): counter = counter + 1 # wait until executed - while not (yield self.issuer.insn_done): + while not ((yield self.issuer.insn_done) or + (yield self.issuer.dbg.terminated_o)): yield # okaaay long story: in overlap mode, PC is updated one cycle -- 2.30.2