diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index e7bed771..35642a23 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -18,13 +18,21 @@ class FrontendReq(implicit p: Parameters) extends CoreBundle()(p) { val speculative = Bool() } +class FrontendExceptions extends Bundle { + val pf = new Bundle { + val inst = Bool() + } + val ae = new Bundle { + val inst = Bool() + } +} + class FrontendResp(implicit p: Parameters) extends CoreBundle()(p) { val btb = Valid(new BTBResp) val pc = UInt(width = vaddrBitsExtended) // ID stage PC val data = UInt(width = fetchWidth * coreInstBits) val mask = Bits(width = fetchWidth) - val pf = Bool() - val ae = Bool() + val xcpt = new FrontendExceptions val replay = Bool() } @@ -83,9 +91,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val s2_btb_resp_valid = Reg(init=Bool(false)) val s2_btb_resp_bits = Reg(new BTBResp) val s2_tlb_resp = Reg(tlb.io.resp) - val s2_pf = s2_tlb_resp.pf.inst && !s2_tlb_resp.miss - val s2_ae = s2_tlb_resp.ae.inst && !s2_tlb_resp.miss - val s2_xcpt = s2_pf || s2_ae + val s2_xcpt = !s2_tlb_resp.miss && fq.io.enq.bits.xcpt.asUInt.orR val s2_speculative = Reg(init=Bool(false)) val fetchBytes = coreInstBytes * fetchWidth @@ -163,8 +169,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) fq.io.enq.bits.data := icache.io.resp.bits fq.io.enq.bits.mask := UInt((1 << fetchWidth)-1) << s2_pc.extract(log2Ceil(fetchWidth)+log2Ceil(coreInstBytes)-1, log2Ceil(coreInstBytes)) - fq.io.enq.bits.pf := s2_pf - fq.io.enq.bits.ae := s2_ae + fq.io.enq.bits.xcpt := s2_tlb_resp fq.io.enq.bits.replay := icache.io.s2_kill && !icache.io.resp.valid && !s2_xcpt fq.io.enq.bits.btb.valid := s2_btb_resp_valid fq.io.enq.bits.btb.bits := s2_btb_resp_bits diff --git a/src/main/scala/rocket/IBuf.scala b/src/main/scala/rocket/IBuf.scala index 1f209729..eb94298a 100644 --- a/src/main/scala/rocket/IBuf.scala +++ b/src/main/scala/rocket/IBuf.scala @@ -9,10 +9,8 @@ import tile._ import util._ class Instruction(implicit val p: Parameters) extends ParameterizedBundle with HasCoreParameters { - val pf0 = Bool() // page fault on first half of instruction - val pf1 = Bool() // page fault on second half of instruction - val ae0 = Bool() // access exception on first half of instruction - val ae1 = Bool() // access exception on second half of instruction + val xcpt0 = new FrontendExceptions // exceptions on first half of instruction + val xcpt1 = new FrontendExceptions // exceptions on second half of instruction val replay = Bool() val btb_hit = Bool() val rvc = Bool() @@ -80,8 +78,7 @@ class IBuf(implicit p: Parameters) extends CoreModule { val valid = (UIntToOH(nValid) - 1)(fetchWidth-1, 0) val bufMask = UIntToOH(nBufValid) - 1 - val pf = valid & (Mux(buf.pf, bufMask, UInt(0)) | Mux(io.imem.bits.pf, ~bufMask, UInt(0))) - val ae = valid & (Mux(buf.ae, bufMask, UInt(0)) | Mux(io.imem.bits.ae, ~bufMask, UInt(0))) + val xcpt = (0 until bufMask.getWidth).map(i => Mux(bufMask(i), buf.xcpt, io.imem.bits.xcpt)) val ic_replay = valid & (Mux(buf.replay, bufMask, UInt(0)) | Mux(io.imem.bits.replay, ~bufMask, UInt(0))) val ibufBTBHitMask = Mux(ibufBTBHit, UIntToOH(ibufBTBResp.bridx), UInt(0)) assert(!io.imem.valid || !io.imem.bits.btb.valid || io.imem.bits.btb.bits.bridx >= pcWordBits) @@ -100,11 +97,9 @@ class IBuf(implicit p: Parameters) extends CoreModule { if (usingCompressed) { val replay = ic_replay(j) || (!exp.io.rvc && (btbHitMask(j) || ic_replay(j+1))) - io.inst(i).valid := valid(j) && (exp.io.rvc || valid(j+1) || pf(j+1) || ae(j+1) || replay) - io.inst(i).bits.pf0 := pf(j) - io.inst(i).bits.pf1 := !exp.io.rvc && pf(j+1) - io.inst(i).bits.ae0 := ae(j) - io.inst(i).bits.ae1 := !exp.io.rvc && ae(j+1) + io.inst(i).valid := valid(j) && (exp.io.rvc || valid(j+1) || xcpt(j+1).asUInt.orR || replay) + io.inst(i).bits.xcpt0 := xcpt(j) + io.inst(i).bits.xcpt1 := Mux(exp.io.rvc, 0.U, xcpt(j+1).asUInt).asTypeOf(new FrontendExceptions) io.inst(i).bits.replay := replay io.inst(i).bits.btb_hit := btbHitMask(j) || (!exp.io.rvc && btbHitMask(j+1)) io.inst(i).bits.rvc := exp.io.rvc @@ -115,10 +110,8 @@ class IBuf(implicit p: Parameters) extends CoreModule { } else { when (io.inst(i).ready) { nReady := i+1 } io.inst(i).valid := valid(i) - io.inst(i).bits.pf0 := pf(i) - io.inst(i).bits.pf1 := false - io.inst(i).bits.ae0 := ae(i) - io.inst(i).bits.ae1 := false + io.inst(i).bits.xcpt0 := xcpt(i) + io.inst(i).bits.xcpt1 := 0.U.asTypeOf(new FrontendExceptions) io.inst(i).bits.replay := ic_replay(i) io.inst(i).bits.rvc := false io.inst(i).bits.btb_hit := btbHitMask(i) diff --git a/src/main/scala/rocket/Rocket.scala b/src/main/scala/rocket/Rocket.scala index 1932724d..b143bcc5 100644 --- a/src/main/scala/rocket/Rocket.scala +++ b/src/main/scala/rocket/Rocket.scala @@ -231,14 +231,16 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) bpu.io.pc := ibuf.io.pc bpu.io.ea := mem_reg_wdata - val id_xcpt_pf = ibuf.io.inst(0).bits.pf0 || ibuf.io.inst(0).bits.pf1 - val id_xcpt_ae = ibuf.io.inst(0).bits.ae0 || ibuf.io.inst(0).bits.ae1 + 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_xcpt_pf, UInt(Causes.fetch_page_fault)), - (id_xcpt_ae, UInt(Causes.fetch_access)), + (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)), + (id_xcpt1.ae.inst, UInt(Causes.fetch_access)), (id_illegal_insn, UInt(Causes.illegal_instruction)))) val dcache_bypass_data = @@ -305,15 +307,15 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) ex_ctrl.alu_dw := DW_XPR ex_ctrl.sel_alu1 := A1_RS1 // badaddr := instruction ex_ctrl.sel_alu2 := A2_ZERO - when (bpu.io.xcpt_if || id_xcpt_pf || id_xcpt_ae) { // badaddr := PC + when (id_xcpt1.asUInt.orR) { // badaddr := PC+2 ex_ctrl.sel_alu1 := A1_PC - } - val pf_second = !ibuf.io.inst(0).bits.pf0 && ibuf.io.inst(0).bits.pf1 - val ae_second = !ibuf.io.inst(0).bits.ae0 && ibuf.io.inst(0).bits.ae1 - when (!bpu.io.xcpt_if && (pf_second || (!id_xcpt_pf && ae_second))) { // badaddr := PC+2 ex_ctrl.sel_alu2 := A2_SIZE ex_reg_rvc := true } + when (bpu.io.xcpt_if || id_xcpt0.asUInt.orR) { // badaddr := PC + ex_ctrl.sel_alu1 := A1_PC + ex_ctrl.sel_alu2 := A2_ZERO + } } ex_reg_flush_pipe := id_ctrl.fence_i || id_csr_flush ex_reg_load_use := id_load_use