Support non-power-of-2 BTBs; prefer invalid entries
This commit is contained in:
		@@ -23,27 +23,29 @@ class rocketDpathBTB(entries: Int) extends Module
 | 
			
		||||
{
 | 
			
		||||
  val io = new DpathBTBIO
 | 
			
		||||
 | 
			
		||||
  val repl_way = LFSR16(io.wen)(log2Up(entries)-1,0) // TODO: pseudo-LRU
 | 
			
		||||
 | 
			
		||||
  var hit_reduction = Bool(false)
 | 
			
		||||
  val hit = Bool()
 | 
			
		||||
  val update = Bool()
 | 
			
		||||
  var update_reduction = Bool(false)
 | 
			
		||||
  val valid = Vec.fill(entries){Reg(init=Bool(false))}
 | 
			
		||||
  val hits = Vec.fill(entries){Bool()}
 | 
			
		||||
  val updates = Vec.fill(entries){Bool()}
 | 
			
		||||
  val targets = Vec.fill(entries){Reg(UInt())}
 | 
			
		||||
  val anyUpdate = updates.toBits.orR
 | 
			
		||||
 | 
			
		||||
  val random_way = Random(entries, io.wen)
 | 
			
		||||
  val invalid_way = valid.indexWhere((x: Bool) => !x)
 | 
			
		||||
  val repl_way = Mux(valid.contains(Bool(false)), invalid_way, random_way)
 | 
			
		||||
 | 
			
		||||
  for (i <- 0 until entries) {
 | 
			
		||||
    val tag = Reg(UInt())
 | 
			
		||||
    val valid = Reg(init=Bool(false))
 | 
			
		||||
    hits(i) := valid && tag === io.current_pc
 | 
			
		||||
    updates(i) := valid && tag === io.correct_pc
 | 
			
		||||
    hits(i) := valid(i) && tag === io.current_pc
 | 
			
		||||
    updates(i) := valid(i) && tag === io.correct_pc
 | 
			
		||||
 | 
			
		||||
    when (io.wen && (updates(i) || !anyUpdate && UInt(i) === repl_way)) {
 | 
			
		||||
      valid := Bool(false)
 | 
			
		||||
      valid(i) := Bool(false)
 | 
			
		||||
      when (!io.clr) {
 | 
			
		||||
        valid := Bool(true)
 | 
			
		||||
        valid(i) := Bool(true)
 | 
			
		||||
        tag := io.correct_pc
 | 
			
		||||
        targets(i) := io.correct_target
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -130,3 +130,21 @@ case class WideCounter(width: Int, inc: Bool = Bool(true))
 | 
			
		||||
    if (isWide) large := (if (w < smallWidth) UInt(0) else x(w.min(width)-1,smallWidth))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object Random
 | 
			
		||||
{
 | 
			
		||||
  def apply(mod: Int, inc: Bool = Bool(true)): UInt = {
 | 
			
		||||
    if (isPow2(mod)) {
 | 
			
		||||
      require(mod <= 65536)
 | 
			
		||||
      LFSR16(inc)(log2Up(mod)-1,0).toUInt
 | 
			
		||||
    } else {
 | 
			
		||||
      val max = 1 << log2Up(mod*8)
 | 
			
		||||
      val rand_pow2 = apply(max, inc)
 | 
			
		||||
 | 
			
		||||
      var res = UInt(mod-1)
 | 
			
		||||
      for (i <- mod-1 to 1 by -1)
 | 
			
		||||
        res = Mux(rand_pow2 < UInt(i*max/mod), UInt(i-1), res)
 | 
			
		||||
      res
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user