[rocket] fix PTW critical path
Pipeline the killing of a D$ request following a PTW cache hit.
This commit is contained in:
parent
7e9d139e49
commit
2ce702dc0a
@ -76,6 +76,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: Nil = Enum(UInt(), 6)
|
val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: Nil = Enum(UInt(), 6)
|
||||||
val state = Reg(init=s_ready)
|
val state = Reg(init=s_ready)
|
||||||
val count = Reg(UInt(width = log2Up(pgLevels)))
|
val count = Reg(UInt(width = log2Up(pgLevels)))
|
||||||
|
val s1_kill = Reg(next = Bool(false))
|
||||||
|
|
||||||
val r_req = Reg(new PTWReq)
|
val r_req = Reg(new PTWReq)
|
||||||
val r_req_dest = Reg(Bits())
|
val r_req_dest = Reg(Bits())
|
||||||
@ -121,12 +122,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
when (hit && state === s_req) { plru.access(OHToUInt(hits)) }
|
when (hit && state === s_req) { plru.access(OHToUInt(hits)) }
|
||||||
when (io.dpath.invalidate) { valid := 0 }
|
when (io.dpath.invalidate) { valid := 0 }
|
||||||
|
|
||||||
(hit, Mux1H(hits, data))
|
(hit && count < pgLevels-1, Mux1H(hits, data))
|
||||||
}
|
|
||||||
|
|
||||||
val set_dirty_bit = pte.access_ok(r_req) && (!pte.a || (r_req.store && !pte.d))
|
|
||||||
when (io.mem.resp.valid && state === s_wait && !set_dirty_bit) {
|
|
||||||
r_pte := pte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val pte_wdata = Wire(init=new PTE().fromBits(0))
|
val pte_wdata = Wire(init=new PTE().fromBits(0))
|
||||||
@ -139,7 +135,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
io.mem.req.bits.typ := MT_D
|
io.mem.req.bits.typ := MT_D
|
||||||
io.mem.req.bits.addr := pte_addr
|
io.mem.req.bits.addr := pte_addr
|
||||||
io.mem.s1_data := pte_wdata.asUInt
|
io.mem.s1_data := pte_wdata.asUInt
|
||||||
io.mem.s1_kill := Bool(false)
|
io.mem.s1_kill := s1_kill
|
||||||
io.mem.invalidate_lr := Bool(false)
|
io.mem.invalidate_lr := Bool(false)
|
||||||
|
|
||||||
val resp_ppns = (0 until pgLevels-1).map(i => Cat(pte_addr >> (pgIdxBits + pgLevelBits*(pgLevels-i-1)), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ (pte_addr >> pgIdxBits)
|
val resp_ppns = (0 until pgLevels-1).map(i => Cat(pte_addr >> (pgIdxBits + pgLevelBits*(pgLevels-i-1)), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ (pte_addr >> pgIdxBits)
|
||||||
@ -161,8 +157,8 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
count := UInt(0)
|
count := UInt(0)
|
||||||
}
|
}
|
||||||
is (s_req) {
|
is (s_req) {
|
||||||
when (pte_cache_hit && count < pgLevels-1) {
|
when (pte_cache_hit) {
|
||||||
io.mem.req.valid := false
|
s1_kill := true
|
||||||
state := s_req
|
state := s_req
|
||||||
count := count + 1
|
count := count + 1
|
||||||
r_pte.ppn := pte_cache_data
|
r_pte.ppn := pte_cache_data
|
||||||
@ -176,8 +172,10 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
}
|
}
|
||||||
when (io.mem.resp.valid) {
|
when (io.mem.resp.valid) {
|
||||||
state := s_done
|
state := s_done
|
||||||
when (set_dirty_bit) {
|
when (pte.access_ok(r_req) && (!pte.a || (r_req.store && !pte.d))) {
|
||||||
state := s_set_dirty
|
state := s_set_dirty
|
||||||
|
}.otherwise {
|
||||||
|
r_pte := pte
|
||||||
}
|
}
|
||||||
when (pte.table() && count < pgLevels-1) {
|
when (pte.table() && count < pgLevels-1) {
|
||||||
state := s_req
|
state := s_req
|
||||||
|
Loading…
Reference in New Issue
Block a user