1
0

Mitigate some more PMP critical paths

This commit is contained in:
Andrew Waterman 2017-03-15 18:00:32 -07:00
parent 7484f27ed3
commit 723352c3e2
5 changed files with 31 additions and 25 deletions

View File

@ -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) {

View File

@ -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
} }

View File

@ -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
}
} }
} }
} }

View File

@ -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 ||

View File

@ -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)