Fix BTB not being refilled on some indirect jumps
We are overloading the BTB-hit signal to mean that any part of the frontend changed the control-flow, not just the BTB. That's the right thing to do for most of the control logic, but it means the BTB sometimes won't get refilled when we'd like it to. This commit makes the frontend use an invalid BTB entry number when it, rather than the BTB, changes the control flow. Since the entry number is invalid, the BTB will treat it as a miss and refill itself. This is kind of a hack, but a more palatable fix requires reworking the RVC IBuf, which I don't have time for right now.
This commit is contained in:
parent
6916e5cbfb
commit
acca0fccf5
@ -11,7 +11,7 @@ import freechips.rocketchip.tile.HasCoreParameters
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class BTBParams(
|
case class BTBParams(
|
||||||
nEntries: Int = 32,
|
nEntries: Int = 30,
|
||||||
nMatchBits: Int = 14,
|
nMatchBits: Int = 14,
|
||||||
nPages: Int = 6,
|
nPages: Int = 6,
|
||||||
nRAS: Int = 6,
|
nRAS: Int = 6,
|
||||||
@ -24,7 +24,6 @@ trait HasBtbParameters extends HasCoreParameters {
|
|||||||
val entries = btbParams.nEntries
|
val entries = btbParams.nEntries
|
||||||
val updatesOutOfOrder = btbParams.updatesOutOfOrder
|
val updatesOutOfOrder = btbParams.updatesOutOfOrder
|
||||||
val nPages = (btbParams.nPages + 1) / 2 * 2 // control logic assumes 2 divides pages
|
val nPages = (btbParams.nPages + 1) / 2 * 2 // control logic assumes 2 divides pages
|
||||||
val opaqueBits = log2Up(entries)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BtbModule(implicit val p: Parameters) extends Module with HasBtbParameters
|
abstract class BtbModule(implicit val p: Parameters) extends Module with HasBtbParameters
|
||||||
@ -141,7 +140,7 @@ class BTBResp(implicit p: Parameters) extends BtbBundle()(p) {
|
|||||||
val mask = Bits(width = fetchWidth)
|
val mask = Bits(width = fetchWidth)
|
||||||
val bridx = Bits(width = log2Up(fetchWidth))
|
val bridx = Bits(width = log2Up(fetchWidth))
|
||||||
val target = UInt(width = vaddrBits)
|
val target = UInt(width = vaddrBits)
|
||||||
val entry = UInt(width = opaqueBits)
|
val entry = UInt(width = log2Up(entries + 1))
|
||||||
val bht = new BHTResp
|
val bht = new BHTResp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +195,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
if (updatesOutOfOrder) {
|
if (updatesOutOfOrder) {
|
||||||
val updateHits = (pageHit << 1)(Mux1H(idxMatch(r_btb_update.bits.pc), idxPages))
|
val updateHits = (pageHit << 1)(Mux1H(idxMatch(r_btb_update.bits.pc), idxPages))
|
||||||
(updateHits.orR, OHToUInt(updateHits))
|
(updateHits.orR, OHToUInt(updateHits))
|
||||||
} else (r_btb_update.bits.prediction.valid, r_btb_update.bits.prediction.bits.entry)
|
} else (r_btb_update.bits.prediction.valid && r_btb_update.bits.prediction.bits.entry < entries, r_btb_update.bits.prediction.bits.entry)
|
||||||
|
|
||||||
val useUpdatePageHit = updatePageHit.orR
|
val useUpdatePageHit = updatePageHit.orR
|
||||||
val usePageHit = pageHit.orR
|
val usePageHit = pageHit.orR
|
||||||
|
@ -259,6 +259,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
|
|||||||
when (taken) {
|
when (taken) {
|
||||||
fq.io.enq.bits.btb.valid := true
|
fq.io.enq.bits.btb.valid := true
|
||||||
fq.io.enq.bits.btb.bits.taken := true
|
fq.io.enq.bits.btb.bits.taken := true
|
||||||
|
fq.io.enq.bits.btb.bits.entry := UInt(tileParams.btb.get.nEntries)
|
||||||
s2_redirect := true
|
s2_redirect := true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user