1
0

Don't allow multiple entries for same PC in BTB

Necessary for RVC forward-progress guarantee.
This commit is contained in:
Andrew Waterman 2016-10-06 09:41:46 -07:00
parent 9b8e8a8b9e
commit 5980dc160f
2 changed files with 22 additions and 0 deletions

View File

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

View File

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