Don't allow multiple entries for same PC in BTB
Necessary for RVC forward-progress guarantee.
This commit is contained in:
		@@ -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.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) {
 | 
			
		||||
    val bht = new BHT(nBHT)
 | 
			
		||||
    val isBranch = !(hits & isJump).orR
 | 
			
		||||
 
 | 
			
		||||
@@ -41,4 +41,21 @@ package object util {
 | 
			
		||||
    // this one's snagged from scalaz
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user