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:
parent
cc2f87c214
commit
3e04a99f61
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user