1
0

Refactor frontend exception passing

Bundle them, and leverage regularity, so that if we have to add more
exceptions in the future, we don't need to change so much code.
This commit is contained in:
Andrew Waterman 2017-06-08 17:44:48 -07:00
parent cc2f87c214
commit 3e04a99f61
3 changed files with 31 additions and 31 deletions

View File

@ -18,13 +18,21 @@ class FrontendReq(implicit p: Parameters) extends CoreBundle()(p) {
val speculative = Bool() 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) { class FrontendResp(implicit p: Parameters) extends CoreBundle()(p) {
val btb = Valid(new BTBResp) val btb = Valid(new BTBResp)
val pc = UInt(width = vaddrBitsExtended) // ID stage PC val pc = UInt(width = vaddrBitsExtended) // ID stage PC
val data = UInt(width = fetchWidth * coreInstBits) val data = UInt(width = fetchWidth * coreInstBits)
val mask = Bits(width = fetchWidth) val mask = Bits(width = fetchWidth)
val pf = Bool() val xcpt = new FrontendExceptions
val ae = Bool()
val replay = Bool() 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_valid = Reg(init=Bool(false))
val s2_btb_resp_bits = Reg(new BTBResp) val s2_btb_resp_bits = Reg(new BTBResp)
val s2_tlb_resp = Reg(tlb.io.resp) val s2_tlb_resp = Reg(tlb.io.resp)
val s2_pf = s2_tlb_resp.pf.inst && !s2_tlb_resp.miss val s2_xcpt = !s2_tlb_resp.miss && fq.io.enq.bits.xcpt.asUInt.orR
val s2_ae = s2_tlb_resp.ae.inst && !s2_tlb_resp.miss
val s2_xcpt = s2_pf || s2_ae
val s2_speculative = Reg(init=Bool(false)) val s2_speculative = Reg(init=Bool(false))
val fetchBytes = coreInstBytes * fetchWidth 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.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.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.xcpt := s2_tlb_resp
fq.io.enq.bits.ae := s2_ae
fq.io.enq.bits.replay := icache.io.s2_kill && !icache.io.resp.valid && !s2_xcpt 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.valid := s2_btb_resp_valid
fq.io.enq.bits.btb.bits := s2_btb_resp_bits fq.io.enq.bits.btb.bits := s2_btb_resp_bits

View File

@ -9,10 +9,8 @@ import tile._
import util._ import util._
class Instruction(implicit val p: Parameters) extends ParameterizedBundle with HasCoreParameters { class Instruction(implicit val p: Parameters) extends ParameterizedBundle with HasCoreParameters {
val pf0 = Bool() // page fault on first half of instruction val xcpt0 = new FrontendExceptions // exceptions on first half of instruction
val pf1 = Bool() // page fault on second half of instruction val xcpt1 = new FrontendExceptions // exceptions 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 replay = Bool() val replay = Bool()
val btb_hit = Bool() val btb_hit = Bool()
val rvc = Bool() val rvc = Bool()
@ -80,8 +78,7 @@ class IBuf(implicit p: Parameters) extends CoreModule {
val valid = (UIntToOH(nValid) - 1)(fetchWidth-1, 0) val valid = (UIntToOH(nValid) - 1)(fetchWidth-1, 0)
val bufMask = UIntToOH(nBufValid) - 1 val bufMask = UIntToOH(nBufValid) - 1
val pf = valid & (Mux(buf.pf, bufMask, UInt(0)) | Mux(io.imem.bits.pf, ~bufMask, UInt(0))) val xcpt = (0 until bufMask.getWidth).map(i => Mux(bufMask(i), buf.xcpt, io.imem.bits.xcpt))
val ae = valid & (Mux(buf.ae, bufMask, UInt(0)) | Mux(io.imem.bits.ae, ~bufMask, UInt(0)))
val ic_replay = valid & (Mux(buf.replay, bufMask, UInt(0)) | Mux(io.imem.bits.replay, ~bufMask, UInt(0))) 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)) 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) 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) { if (usingCompressed) {
val replay = ic_replay(j) || (!exp.io.rvc && (btbHitMask(j) || ic_replay(j+1))) 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).valid := valid(j) && (exp.io.rvc || valid(j+1) || xcpt(j+1).asUInt.orR || replay)
io.inst(i).bits.pf0 := pf(j) io.inst(i).bits.xcpt0 := xcpt(j)
io.inst(i).bits.pf1 := !exp.io.rvc && pf(j+1) io.inst(i).bits.xcpt1 := Mux(exp.io.rvc, 0.U, xcpt(j+1).asUInt).asTypeOf(new FrontendExceptions)
io.inst(i).bits.ae0 := ae(j)
io.inst(i).bits.ae1 := !exp.io.rvc && ae(j+1)
io.inst(i).bits.replay := replay io.inst(i).bits.replay := replay
io.inst(i).bits.btb_hit := btbHitMask(j) || (!exp.io.rvc && btbHitMask(j+1)) io.inst(i).bits.btb_hit := btbHitMask(j) || (!exp.io.rvc && btbHitMask(j+1))
io.inst(i).bits.rvc := exp.io.rvc io.inst(i).bits.rvc := exp.io.rvc
@ -115,10 +110,8 @@ class IBuf(implicit p: Parameters) extends CoreModule {
} else { } else {
when (io.inst(i).ready) { nReady := i+1 } when (io.inst(i).ready) { nReady := i+1 }
io.inst(i).valid := valid(i) io.inst(i).valid := valid(i)
io.inst(i).bits.pf0 := pf(i) io.inst(i).bits.xcpt0 := xcpt(i)
io.inst(i).bits.pf1 := false io.inst(i).bits.xcpt1 := 0.U.asTypeOf(new FrontendExceptions)
io.inst(i).bits.ae0 := ae(i)
io.inst(i).bits.ae1 := false
io.inst(i).bits.replay := ic_replay(i) io.inst(i).bits.replay := ic_replay(i)
io.inst(i).bits.rvc := false io.inst(i).bits.rvc := false
io.inst(i).bits.btb_hit := btbHitMask(i) io.inst(i).bits.btb_hit := btbHitMask(i)

View File

@ -231,14 +231,16 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
bpu.io.pc := ibuf.io.pc bpu.io.pc := ibuf.io.pc
bpu.io.ea := mem_reg_wdata bpu.io.ea := mem_reg_wdata
val id_xcpt_pf = ibuf.io.inst(0).bits.pf0 || ibuf.io.inst(0).bits.pf1 val id_xcpt0 = ibuf.io.inst(0).bits.xcpt0
val id_xcpt_ae = ibuf.io.inst(0).bits.ae0 || ibuf.io.inst(0).bits.ae1 val id_xcpt1 = ibuf.io.inst(0).bits.xcpt1
val (id_xcpt, id_cause) = checkExceptions(List( val (id_xcpt, id_cause) = checkExceptions(List(
(csr.io.interrupt, csr.io.interrupt_cause), (csr.io.interrupt, csr.io.interrupt_cause),
(bpu.io.debug_if, UInt(CSR.debugTriggerCause)), (bpu.io.debug_if, UInt(CSR.debugTriggerCause)),
(bpu.io.xcpt_if, UInt(Causes.breakpoint)), (bpu.io.xcpt_if, UInt(Causes.breakpoint)),
(id_xcpt_pf, UInt(Causes.fetch_page_fault)), (id_xcpt0.pf.inst, UInt(Causes.fetch_page_fault)),
(id_xcpt_ae, UInt(Causes.fetch_access)), (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)))) (id_illegal_insn, UInt(Causes.illegal_instruction))))
val dcache_bypass_data = val dcache_bypass_data =
@ -305,15 +307,15 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
ex_ctrl.alu_dw := DW_XPR ex_ctrl.alu_dw := DW_XPR
ex_ctrl.sel_alu1 := A1_RS1 // badaddr := instruction ex_ctrl.sel_alu1 := A1_RS1 // badaddr := instruction
ex_ctrl.sel_alu2 := A2_ZERO 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 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_ctrl.sel_alu2 := A2_SIZE
ex_reg_rvc := true 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_flush_pipe := id_ctrl.fence_i || id_csr_flush
ex_reg_load_use := id_load_use ex_reg_load_use := id_load_use