Guarantee one-hotness of BTB entries
This commit is contained in:
parent
c0e6ecebfc
commit
35a983275e
@ -147,6 +147,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
val tgts = Reg(Vec(entries, UInt(width=matchBits)))
|
val tgts = Reg(Vec(entries, UInt(width=matchBits)))
|
||||||
val tgtPages = Reg(Vec(entries, UInt(width=log2Up(nPages))))
|
val tgtPages = Reg(Vec(entries, UInt(width=log2Up(nPages))))
|
||||||
val pages = Reg(Vec(nPages, UInt(width=vaddrBits-matchBits)))
|
val pages = Reg(Vec(nPages, UInt(width=vaddrBits-matchBits)))
|
||||||
|
val pageValid = Reg(init = UInt(0, nPages))
|
||||||
val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0))
|
val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0))
|
||||||
val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0))
|
val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0))
|
||||||
|
|
||||||
@ -157,12 +158,12 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
private def page(addr: UInt) = addr >> matchBits
|
private def page(addr: UInt) = addr >> matchBits
|
||||||
private def pageMatch(addr: UInt) = {
|
private def pageMatch(addr: UInt) = {
|
||||||
val p = page(addr)
|
val p = page(addr)
|
||||||
pages.map(_ === p).toBits
|
pageValid & pages.map(_ === p).toBits
|
||||||
}
|
}
|
||||||
private def tagMatch(addr: UInt, pgMatch: UInt) = {
|
private def tagMatch(addr: UInt, pgMatch: UInt) = {
|
||||||
val idxMatch = idxs.map(_ === addr(matchBits-1,0))
|
val idxMatch = idxs.map(_ === addr(matchBits-1,0)).toBits
|
||||||
val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR)
|
val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR).toBits
|
||||||
(idxPageMatch zip idxMatch) map { case (p, i) => p && i }
|
idxMatch & idxPageMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
val r_btb_update = Pipe(io.btb_update)
|
val r_btb_update = Pipe(io.btb_update)
|
||||||
@ -172,16 +173,20 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
val hitsVec = tagMatch(io.req.bits.addr, pageHit)
|
val hitsVec = tagMatch(io.req.bits.addr, pageHit)
|
||||||
val hits = hitsVec.toBits
|
val hits = hitsVec.toBits
|
||||||
val updatePageHit = pageMatch(r_btb_update.bits.pc)
|
val updatePageHit = pageMatch(r_btb_update.bits.pc)
|
||||||
val updateHits = tagMatch(r_btb_update.bits.pc, updatePageHit)
|
|
||||||
|
|
||||||
val updateHit = r_btb_update.bits.prediction.valid
|
val updateHits = tagMatch(r_btb_update.bits.pc, updatePageHit)
|
||||||
val nextRepl = Reg(UInt(width = log2Ceil(entries)))
|
val updateHit = if (updatesOutOfOrder) updateHits.orR else r_btb_update.bits.prediction.valid
|
||||||
when (r_btb_update.valid && !updateHit) { nextRepl := Mux(nextRepl === entries-1 && Bool(!isPow2(entries)), 0, nextRepl + 1) }
|
val updateHitAddr = if (updatesOutOfOrder) OHToUInt(updateHits) else r_btb_update.bits.prediction.bits.entry
|
||||||
val nextPageRepl = Reg(UInt(width = log2Ceil(nPages)))
|
|
||||||
|
// guarantee one-hotness of idx after reset
|
||||||
|
val resetting = Reg(init = Bool(true))
|
||||||
|
val (nextRepl, wrap) = Counter(resetting || (r_btb_update.valid && !updateHit), entries)
|
||||||
|
when (wrap) { resetting := false }
|
||||||
|
|
||||||
val useUpdatePageHit = updatePageHit.orR
|
val useUpdatePageHit = updatePageHit.orR
|
||||||
val usePageHit = pageHit.orR
|
val usePageHit = pageHit.orR
|
||||||
val doIdxPageRepl = !useUpdatePageHit
|
val doIdxPageRepl = !useUpdatePageHit
|
||||||
|
val nextPageRepl = Reg(UInt(width = log2Ceil(nPages)))
|
||||||
val idxPageRepl = Mux(usePageHit, Cat(pageHit(nPages-2,0), pageHit(nPages-1)), UIntToOH(nextPageRepl))
|
val idxPageRepl = Mux(usePageHit, Cat(pageHit(nPages-2,0), pageHit(nPages-1)), UIntToOH(nextPageRepl))
|
||||||
val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl)
|
val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl)
|
||||||
val idxPageUpdate = OHToUInt(idxPageUpdateOH)
|
val idxPageUpdate = OHToUInt(idxPageUpdateOH)
|
||||||
@ -199,18 +204,15 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
nextPageRepl := Mux(next >= nPages, next(0), next)
|
nextPageRepl := Mux(next >= nPages, next(0), next)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (r_btb_update.valid) {
|
when (r_btb_update.valid || resetting) {
|
||||||
assert(io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
|
assert(resetting || io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
|
||||||
|
|
||||||
val waddr =
|
val waddr = Mux(updateHit && !resetting, updateHitAddr, nextRepl)
|
||||||
if (updatesOutOfOrder) Mux(updateHits.reduce(_|_), OHToUInt(updateHits), nextRepl)
|
val mask = UIntToOH(waddr)
|
||||||
else Mux(updateHit, r_btb_update.bits.prediction.bits.entry, nextRepl)
|
idxs(waddr) := Mux(resetting, Cat(r_btb_update.bits.pc >> log2Ceil(entries), nextRepl), r_btb_update.bits.pc)
|
||||||
|
|
||||||
idxs(waddr) := r_btb_update.bits.pc
|
|
||||||
tgts(waddr) := update_target
|
tgts(waddr) := update_target
|
||||||
idxPages(waddr) := idxPageUpdate
|
idxPages(waddr) := idxPageUpdate
|
||||||
tgtPages(waddr) := tgtPageUpdate
|
tgtPages(waddr) := tgtPageUpdate
|
||||||
val mask = UIntToOH(waddr)
|
|
||||||
useRAS := Mux(r_btb_update.bits.isReturn, useRAS | mask, useRAS & ~mask)
|
useRAS := Mux(r_btb_update.bits.isReturn, useRAS | mask, useRAS & ~mask)
|
||||||
isJump := Mux(r_btb_update.bits.isJump, isJump | mask, isJump & ~mask)
|
isJump := Mux(r_btb_update.bits.isJump, isJump | mask, isJump & ~mask)
|
||||||
if (fetchWidth > 1)
|
if (fetchWidth > 1)
|
||||||
@ -227,6 +229,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target)))
|
Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target)))
|
||||||
writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn),
|
writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn),
|
||||||
Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc)))
|
Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc)))
|
||||||
|
pageValid := pageValid | tgtPageReplEn | idxPageReplEn
|
||||||
}
|
}
|
||||||
|
|
||||||
io.resp.valid := hits.orR
|
io.resp.valid := hits.orR
|
||||||
|
Loading…
Reference in New Issue
Block a user