diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index dd8653b6..80d3b1e7 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -72,7 +72,9 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val s2_pc = Reg(init=io.resetVector) val s2_btb_resp_valid = Reg(init=Bool(false)) val s2_btb_resp_bits = Reg(new BTBResp) - val s2_xcpt_if = Reg(init=Bool(false)) + val s2_maybe_xcpt_if = Reg(init=Bool(false)) + val s2_tlb_miss = Reg(Bool()) + val s2_xcpt_if = s2_maybe_xcpt_if && !s2_tlb_miss val s2_speculative = Reg(init=Bool(false)) val s2_cacheable = Reg(init=Bool(false)) @@ -99,7 +101,8 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) s2_pc := s1_pc s2_speculative := s1_speculative s2_cacheable := tlb.io.resp.cacheable - s2_xcpt_if := tlb.io.resp.xcpt_if && !tlb.io.resp.miss + s2_maybe_xcpt_if := tlb.io.resp.xcpt_if + s2_tlb_miss := tlb.io.resp.miss } } when (io.cpu.req.valid) { diff --git a/src/main/scala/rocket/PMP.scala b/src/main/scala/rocket/PMP.scala index 89968dc2..285efc67 100644 --- a/src/main/scala/rocket/PMP.scala +++ b/src/main/scala/rocket/PMP.scala @@ -30,7 +30,7 @@ class PMP(implicit p: Parameters) extends CoreBundle()(p) { def pow2AddressMatch(x: UInt, lgSize: UInt, lgMaxSize: Int) = { val m = mask - def checkOne(a: UInt) = (~(a >> lgAlign) | m) === (~addr | m) + def checkOne(a: UInt) = (((a >> lgAlign) ^ addr) & ~m) === 0 var res = checkOne(x) for (i <- (1 << lgAlign) until (1 << lgMaxSize) by (1 << lgAlign)) res = res || (lgSize > log2Ceil(i) && checkOne(x | i)) @@ -49,9 +49,9 @@ class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p) val pmp = Vec(nPMPs, new PMP).asInput val addr = UInt(INPUT, paddrBits) val size = UInt(INPUT, log2Ceil(lgMaxSize + 1)) - val xcpt_if = Bool(OUTPUT) - val xcpt_ld = Bool(OUTPUT) - val xcpt_st = Bool(OUTPUT) + val r = Bool(OUTPUT) + val w = Bool(OUTPUT) + val x = Bool(OUTPUT) } def hits = io.pmp.map(_.hit(io.prv, io.addr, io.size, lgMaxSize)) @@ -60,7 +60,7 @@ class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p) MuxT(hit && pmp.cfg.p >= pri, (pmp.cfg.r, pmp.cfg.w, pmp.cfg.x, pmp.cfg.p), (r, w, x, pri)) } - io.xcpt_if := !x - io.xcpt_ld := !r - io.xcpt_st := !w + io.r := r + io.w := w + io.x := x } diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 72dfcc45..e3e4ec95 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -79,6 +79,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { val count = Reg(UInt(width = log2Up(pgLevels))) val s1_kill = Reg(next = Bool(false)) val resp_valid = Reg(next = Bool(false)) + val exception = Reg(next = io.mem.xcpt.pf.ld) val r_req = Reg(new PTWReq) val r_req_dest = Reg(Bits()) @@ -156,7 +157,6 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { is (s_req) { when (pte_cache_hit) { s1_kill := true - state := s_req count := count + 1 r_pte.ppn := pte_cache_data }.elsewhen (io.mem.req.ready) { @@ -165,11 +165,6 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { } is (s_wait1) { state := s_wait2 - when (io.mem.xcpt.pf.ld) { - r_pte.v := false - state := s_ready - resp_valid := true - } } is (s_wait2) { when (io.mem.s2_nack) { @@ -185,6 +180,11 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { resp_valid := true } } + when (exception) { + r_pte.v := false + state := s_ready + resp_valid := true + } } } } diff --git a/src/main/scala/rocket/Rocket.scala b/src/main/scala/rocket/Rocket.scala index f86eb9f7..5b87a821 100644 --- a/src/main/scala/rocket/Rocket.scala +++ b/src/main/scala/rocket/Rocket.scala @@ -392,9 +392,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) (mem_breakpoint, UInt(Causes.breakpoint)), (mem_npc_misaligned, UInt(Causes.misaligned_fetch)), (mem_ctrl.mem && io.dmem.xcpt.ma.st, UInt(Causes.misaligned_store)), - (mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)), - (mem_ctrl.mem && io.dmem.xcpt.pf.st, UInt(Causes.fault_store)), - (mem_ctrl.mem && io.dmem.xcpt.pf.ld, UInt(Causes.fault_load)))) + (mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)))) val (mem_xcpt, mem_cause) = checkExceptions(List( (mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), @@ -423,12 +421,17 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) wb_reg_pc := mem_reg_pc } + val (wb_xcpt, wb_cause) = checkExceptions(List( + (wb_reg_xcpt, wb_reg_cause), + (wb_reg_valid && wb_ctrl.mem && RegEnable(io.dmem.xcpt.pf.st, mem_pc_valid), UInt(Causes.fault_store)), + (wb_reg_valid && wb_ctrl.mem && RegEnable(io.dmem.xcpt.pf.ld, mem_pc_valid), UInt(Causes.fault_load)) + )) + val wb_wxd = wb_reg_valid && wb_ctrl.wxd val wb_set_sboard = wb_ctrl.div || wb_dcache_miss || wb_ctrl.rocc val replay_wb_common = io.dmem.s2_nack || wb_reg_replay val replay_wb_rocc = wb_reg_valid && wb_ctrl.rocc && !io.rocc.cmd.ready val replay_wb = replay_wb_common || replay_wb_rocc - val wb_xcpt = wb_reg_xcpt take_pc_wb := replay_wb || wb_xcpt || csr.io.eret // writeback arbitration @@ -473,8 +476,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) // hook up control/status regfile csr.io.decode.csr := ibuf.io.inst(0).bits.raw(31,20) - csr.io.exception := wb_reg_xcpt - csr.io.cause := wb_reg_cause + csr.io.exception := wb_xcpt + csr.io.cause := wb_cause csr.io.retire := wb_valid csr.io.interrupts := io.interrupts csr.io.hartid := io.hartid @@ -536,7 +539,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val dcache_blocked = Reg(Bool()) dcache_blocked := !io.dmem.req.ready && (io.dmem.req.valid || dcache_blocked) val rocc_blocked = Reg(Bool()) - rocc_blocked := !wb_reg_xcpt && !io.rocc.cmd.ready && (io.rocc.cmd.valid || rocc_blocked) + rocc_blocked := !wb_xcpt && !io.rocc.cmd.ready && (io.rocc.cmd.valid || rocc_blocked) val ctrl_stalld = id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard || diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index 88736c8c..8a7b8bbf 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -84,9 +84,9 @@ class TLB(lgMaxSize: Int, entries: Int)(implicit edge: TLEdgeOut, p: Parameters) val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_) def fastCheck(member: TLManagerParameters => Boolean) = legal_address && Mux1H(edge.manager.findFast(mpu_physaddr), edge.manager.managers.map(m => Bool(member(m)))) - val prot_r = fastCheck(_.supportsGet) && !pmp.io.xcpt_ld - val prot_w = fastCheck(_.supportsPutFull) && !pmp.io.xcpt_st - val prot_x = fastCheck(_.executable) && !pmp.io.xcpt_if + val prot_r = fastCheck(_.supportsGet) && pmp.io.r + val prot_w = fastCheck(_.supportsPutFull) && pmp.io.w + val prot_x = fastCheck(_.executable) && pmp.io.x val cacheable = fastCheck(_.supportsAcquireB) val isSpecial = { val homogeneous = Wire(init = false.B)