Mitigate some more PMP critical paths
This commit is contained in:
parent
7484f27ed3
commit
723352c3e2
@ -72,7 +72,9 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
|
|||||||
val s2_pc = Reg(init=io.resetVector)
|
val s2_pc = Reg(init=io.resetVector)
|
||||||
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_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_speculative = Reg(init=Bool(false))
|
||||||
val s2_cacheable = 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_pc := s1_pc
|
||||||
s2_speculative := s1_speculative
|
s2_speculative := s1_speculative
|
||||||
s2_cacheable := tlb.io.resp.cacheable
|
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) {
|
when (io.cpu.req.valid) {
|
||||||
|
@ -30,7 +30,7 @@ class PMP(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
|
|
||||||
def pow2AddressMatch(x: UInt, lgSize: UInt, lgMaxSize: Int) = {
|
def pow2AddressMatch(x: UInt, lgSize: UInt, lgMaxSize: Int) = {
|
||||||
val m = mask
|
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)
|
var res = checkOne(x)
|
||||||
for (i <- (1 << lgAlign) until (1 << lgMaxSize) by (1 << lgAlign))
|
for (i <- (1 << lgAlign) until (1 << lgMaxSize) by (1 << lgAlign))
|
||||||
res = res || (lgSize > log2Ceil(i) && checkOne(x | i))
|
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 pmp = Vec(nPMPs, new PMP).asInput
|
||||||
val addr = UInt(INPUT, paddrBits)
|
val addr = UInt(INPUT, paddrBits)
|
||||||
val size = UInt(INPUT, log2Ceil(lgMaxSize + 1))
|
val size = UInt(INPUT, log2Ceil(lgMaxSize + 1))
|
||||||
val xcpt_if = Bool(OUTPUT)
|
val r = Bool(OUTPUT)
|
||||||
val xcpt_ld = Bool(OUTPUT)
|
val w = Bool(OUTPUT)
|
||||||
val xcpt_st = Bool(OUTPUT)
|
val x = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
def hits = io.pmp.map(_.hit(io.prv, io.addr, io.size, lgMaxSize))
|
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))
|
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.r := r
|
||||||
io.xcpt_ld := !r
|
io.w := w
|
||||||
io.xcpt_st := !w
|
io.x := x
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
val count = Reg(UInt(width = log2Up(pgLevels)))
|
val count = Reg(UInt(width = log2Up(pgLevels)))
|
||||||
val s1_kill = Reg(next = Bool(false))
|
val s1_kill = Reg(next = Bool(false))
|
||||||
val resp_valid = 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 = Reg(new PTWReq)
|
||||||
val r_req_dest = Reg(Bits())
|
val r_req_dest = Reg(Bits())
|
||||||
@ -156,7 +157,6 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
is (s_req) {
|
is (s_req) {
|
||||||
when (pte_cache_hit) {
|
when (pte_cache_hit) {
|
||||||
s1_kill := true
|
s1_kill := true
|
||||||
state := s_req
|
|
||||||
count := count + 1
|
count := count + 1
|
||||||
r_pte.ppn := pte_cache_data
|
r_pte.ppn := pte_cache_data
|
||||||
}.elsewhen (io.mem.req.ready) {
|
}.elsewhen (io.mem.req.ready) {
|
||||||
@ -165,11 +165,6 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
}
|
}
|
||||||
is (s_wait1) {
|
is (s_wait1) {
|
||||||
state := s_wait2
|
state := s_wait2
|
||||||
when (io.mem.xcpt.pf.ld) {
|
|
||||||
r_pte.v := false
|
|
||||||
state := s_ready
|
|
||||||
resp_valid := true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is (s_wait2) {
|
is (s_wait2) {
|
||||||
when (io.mem.s2_nack) {
|
when (io.mem.s2_nack) {
|
||||||
@ -185,6 +180,11 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
resp_valid := true
|
resp_valid := true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
when (exception) {
|
||||||
|
r_pte.v := false
|
||||||
|
state := s_ready
|
||||||
|
resp_valid := true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,9 +392,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
(mem_breakpoint, UInt(Causes.breakpoint)),
|
(mem_breakpoint, UInt(Causes.breakpoint)),
|
||||||
(mem_npc_misaligned, UInt(Causes.misaligned_fetch)),
|
(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.st, UInt(Causes.misaligned_store)),
|
||||||
(mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)),
|
(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))))
|
|
||||||
|
|
||||||
val (mem_xcpt, mem_cause) = checkExceptions(List(
|
val (mem_xcpt, mem_cause) = checkExceptions(List(
|
||||||
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause),
|
(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
|
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_wxd = wb_reg_valid && wb_ctrl.wxd
|
||||||
val wb_set_sboard = wb_ctrl.div || wb_dcache_miss || wb_ctrl.rocc
|
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_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_rocc = wb_reg_valid && wb_ctrl.rocc && !io.rocc.cmd.ready
|
||||||
val replay_wb = replay_wb_common || replay_wb_rocc
|
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
|
take_pc_wb := replay_wb || wb_xcpt || csr.io.eret
|
||||||
|
|
||||||
// writeback arbitration
|
// writeback arbitration
|
||||||
@ -473,8 +476,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
|
|
||||||
// hook up control/status regfile
|
// hook up control/status regfile
|
||||||
csr.io.decode.csr := ibuf.io.inst(0).bits.raw(31,20)
|
csr.io.decode.csr := ibuf.io.inst(0).bits.raw(31,20)
|
||||||
csr.io.exception := wb_reg_xcpt
|
csr.io.exception := wb_xcpt
|
||||||
csr.io.cause := wb_reg_cause
|
csr.io.cause := wb_cause
|
||||||
csr.io.retire := wb_valid
|
csr.io.retire := wb_valid
|
||||||
csr.io.interrupts := io.interrupts
|
csr.io.interrupts := io.interrupts
|
||||||
csr.io.hartid := io.hartid
|
csr.io.hartid := io.hartid
|
||||||
@ -536,7 +539,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val dcache_blocked = Reg(Bool())
|
val dcache_blocked = Reg(Bool())
|
||||||
dcache_blocked := !io.dmem.req.ready && (io.dmem.req.valid || dcache_blocked)
|
dcache_blocked := !io.dmem.req.ready && (io.dmem.req.valid || dcache_blocked)
|
||||||
val rocc_blocked = Reg(Bool())
|
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 =
|
val ctrl_stalld =
|
||||||
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
id_ex_hazard || id_mem_hazard || id_wb_hazard || id_sboard_hazard ||
|
||||||
|
@ -84,9 +84,9 @@ class TLB(lgMaxSize: Int, entries: Int)(implicit edge: TLEdgeOut, p: Parameters)
|
|||||||
val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
|
val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
|
||||||
def fastCheck(member: TLManagerParameters => Boolean) =
|
def fastCheck(member: TLManagerParameters => Boolean) =
|
||||||
legal_address && Mux1H(edge.manager.findFast(mpu_physaddr), edge.manager.managers.map(m => Bool(member(m))))
|
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_r = fastCheck(_.supportsGet) && pmp.io.r
|
||||||
val prot_w = fastCheck(_.supportsPutFull) && !pmp.io.xcpt_st
|
val prot_w = fastCheck(_.supportsPutFull) && pmp.io.w
|
||||||
val prot_x = fastCheck(_.executable) && !pmp.io.xcpt_if
|
val prot_x = fastCheck(_.executable) && pmp.io.x
|
||||||
val cacheable = fastCheck(_.supportsAcquireB)
|
val cacheable = fastCheck(_.supportsAcquireB)
|
||||||
val isSpecial = {
|
val isSpecial = {
|
||||||
val homogeneous = Wire(init = false.B)
|
val homogeneous = Wire(init = false.B)
|
||||||
|
Loading…
Reference in New Issue
Block a user