From c1ee31d133aadd88e4ec27fd121de9a99c4cb531 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 22 Feb 2018 14:56:57 -0800 Subject: [PATCH 1/2] 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. --- src/main/scala/rocket/RocketCore.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 0f3101c0..d66bade9 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -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_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( - (mem_debug_breakpoint, UInt(CSR.debugTriggerCause)), - (mem_breakpoint, UInt(Causes.breakpoint)), - (mem_npc_misaligned, UInt(Causes.misaligned_fetch)))) + val (mem_ldst_xcpt, mem_ldst_cause) = checkExceptions(List( + (mem_debug_breakpoint, UInt(CSR.debugTriggerCause)), + (mem_breakpoint, UInt(Causes.breakpoint)))) val (mem_xcpt, mem_cause) = checkExceptions(List( (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( (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.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_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.exception := wb_xcpt && csr.io.status.xs.orR From aad75f2285bcc0f90c5f97d0b4ec8042a9f7c515 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 22 Feb 2018 15:12:19 -0800 Subject: [PATCH 2/2] Implement misa.C proposal This proposal hasn't been adopted yet, but anything is better than the current implementation, where clearing misa.C when the PC is misaligned is effectively undefined. --- src/main/scala/rocket/CSR.scala | 2 +- src/main/scala/rocket/RocketCore.scala | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 0bf870df..0578a2fb 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -837,6 +837,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param when (decoded_addr(lo)) { ctr := wdata(ctr.getWidth-1, 0) } } } - def formEPC(x: UInt) = ~(~x | Cat(!reg_misa('c'-'a'), UInt(1))) + def formEPC(x: UInt) = ~(~x | (if (usingCompressed) 1.U else 3.U)) def isaStringToMask(s: String) = s.map(x => 1 << (x - 'A')).foldLeft(0)(_|_) } diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index d66bade9..681eceec 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -228,12 +228,14 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) bpu.io.pc := ibuf.io.pc bpu.io.ea := mem_reg_wdata + val id_pc_misaligned = !csr.io.status.isa('c'-'a') && ibuf.io.pc(1) val id_xcpt0 = ibuf.io.inst(0).bits.xcpt0 val id_xcpt1 = ibuf.io.inst(0).bits.xcpt1 val (id_xcpt, id_cause) = checkExceptions(List( (csr.io.interrupt, csr.io.interrupt_cause), (bpu.io.debug_if, UInt(CSR.debugTriggerCause)), (bpu.io.xcpt_if, UInt(Causes.breakpoint)), + (id_pc_misaligned, UInt(Causes.misaligned_fetch)), (id_xcpt0.pf.inst, UInt(Causes.fetch_page_fault)), (id_xcpt0.ae.inst, UInt(Causes.fetch_access)), (id_xcpt1.pf.inst, UInt(Causes.fetch_page_fault)),