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.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)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user