1
0

Fix debug trigger point for stores

In Rocket, debug triggers are supposed to happen before a store
occurs, rather than after.  Previously, we reported the exception
on the store's PC, but the store occurred anyway.  This probably
hasn't been problematic in practice because most stores are
idempotent.
This commit is contained in:
Andrew Waterman 2018-02-22 14:56:57 -08:00
parent 32c5c3c04d
commit c1ee31d133

View File

@ -427,14 +427,14 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
val mem_breakpoint = (mem_reg_load && bpu.io.xcpt_ld) || (mem_reg_store && bpu.io.xcpt_st) val mem_breakpoint = (mem_reg_load && bpu.io.xcpt_ld) || (mem_reg_store && bpu.io.xcpt_st)
val mem_debug_breakpoint = (mem_reg_load && bpu.io.debug_ld) || (mem_reg_store && bpu.io.debug_st) val mem_debug_breakpoint = (mem_reg_load && bpu.io.debug_ld) || (mem_reg_store && bpu.io.debug_st)
val (mem_new_xcpt, mem_new_cause) = checkExceptions(List( val (mem_ldst_xcpt, mem_ldst_cause) = checkExceptions(List(
(mem_debug_breakpoint, UInt(CSR.debugTriggerCause)), (mem_debug_breakpoint, UInt(CSR.debugTriggerCause)),
(mem_breakpoint, UInt(Causes.breakpoint)), (mem_breakpoint, UInt(Causes.breakpoint))))
(mem_npc_misaligned, UInt(Causes.misaligned_fetch))))
val (mem_xcpt, mem_cause) = checkExceptions(List( val (mem_xcpt, mem_cause) = checkExceptions(List(
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), (mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause),
(mem_reg_valid && mem_new_xcpt, mem_new_cause))) (mem_reg_valid && mem_npc_misaligned, UInt(Causes.misaligned_fetch)),
(mem_reg_valid && mem_ldst_xcpt, mem_ldst_cause)))
val memCoverCauses = (exCoverCauses ++ List( val memCoverCauses = (exCoverCauses ++ List(
(CSR.debugTriggerCause, "DEBUG_TRIGGER"), (CSR.debugTriggerCause, "DEBUG_TRIGGER"),
@ -677,7 +677,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
io.dmem.req.bits.addr := encodeVirtualAddress(ex_rs(0), alu.io.adder_out) io.dmem.req.bits.addr := encodeVirtualAddress(ex_rs(0), alu.io.adder_out)
io.dmem.invalidate_lr := wb_xcpt io.dmem.invalidate_lr := wb_xcpt
io.dmem.s1_data.data := (if (fLen == 0) mem_reg_rs2 else Mux(mem_ctrl.fp, Fill((xLen max fLen) / fLen, io.fpu.store_data), mem_reg_rs2)) io.dmem.s1_data.data := (if (fLen == 0) mem_reg_rs2 else Mux(mem_ctrl.fp, Fill((xLen max fLen) / fLen, io.fpu.store_data), mem_reg_rs2))
io.dmem.s1_kill := killm_common || mem_breakpoint io.dmem.s1_kill := killm_common || mem_ldst_xcpt
io.rocc.cmd.valid := wb_reg_valid && wb_ctrl.rocc && !replay_wb_common io.rocc.cmd.valid := wb_reg_valid && wb_ctrl.rocc && !replay_wb_common
io.rocc.exception := wb_xcpt && csr.io.status.xs.orR io.rocc.exception := wb_xcpt && csr.io.status.xs.orR