# 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
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):
comb = m.d.comb
sync = m.d.sync
+ dbg = self.dbg
pdecode2 = self.pdecode2
# temporaries
~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)
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:
# 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
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