Don't allow multiple entries for same PC in BTB
Necessary for RVC forward-progress guarantee.
This commit is contained in:
parent
9b8e8a8b9e
commit
5980dc160f
@ -246,6 +246,11 @@ class BTB(implicit p: Parameters) extends BtbModule {
|
|||||||
io.resp.bits.bridx := (if (fetchWidth > 1) Mux1H(hitsVec, brIdx) else UInt(0))
|
io.resp.bits.bridx := (if (fetchWidth > 1) Mux1H(hitsVec, brIdx) else UInt(0))
|
||||||
io.resp.bits.mask := Cat((UInt(1) << ~Mux(io.resp.bits.taken, ~io.resp.bits.bridx, UInt(0)))-1, UInt(1))
|
io.resp.bits.mask := Cat((UInt(1) << ~Mux(io.resp.bits.taken, ~io.resp.bits.bridx, UInt(0)))-1, UInt(1))
|
||||||
|
|
||||||
|
// if multiple entries for same PC land in BTB, zap them
|
||||||
|
when (PopCountAtLeast(hits, 2)) {
|
||||||
|
isValid := isValid & ~hits
|
||||||
|
}
|
||||||
|
|
||||||
if (nBHT > 0) {
|
if (nBHT > 0) {
|
||||||
val bht = new BHT(nBHT)
|
val bht = new BHT(nBHT)
|
||||||
val isBranch = !(hits & isJump).orR
|
val isBranch = !(hits & isJump).orR
|
||||||
|
@ -41,4 +41,21 @@ package object util {
|
|||||||
// this one's snagged from scalaz
|
// this one's snagged from scalaz
|
||||||
def option[T](z: => T): Option[T] = if (x) Some(z) else None
|
def option[T](z: => T): Option[T] = if (x) Some(z) else None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object PopCountAtLeast {
|
||||||
|
private def two(x: UInt): (Bool, Bool) = x.getWidth match {
|
||||||
|
case 1 => (Bool(true), Bool(false))
|
||||||
|
case n =>
|
||||||
|
val half = x.getWidth / 2
|
||||||
|
val (leftOne, leftTwo) = two(x(half - 1, 0))
|
||||||
|
val (rightOne, rightTwo) = two(x(x.getWidth - 1, half))
|
||||||
|
(leftOne || rightOne, leftTwo || rightTwo || (leftOne && rightOne))
|
||||||
|
}
|
||||||
|
def apply(x: UInt, n: Int): Bool = n match {
|
||||||
|
case 0 => Bool(true)
|
||||||
|
case 1 => x.orR
|
||||||
|
case 2 => two(x)._2
|
||||||
|
case 3 => PopCount(x) >= UInt(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user