Tage.scala 18.9 KB
Newer Older
L
Lingrui98 已提交
1 2 3 4 5 6 7 8 9
package xiangshan.frontend

import chisel3._
import chisel3.util._
import xiangshan._
import utils._

import scala.math.min

L
Lingrui98 已提交
10 11 12 13 14 15 16 17 18
trait HasTageParameter extends HasXSParameter{
  //                   Sets  Hist   Tag
  val TableInfo = Seq(( 128,    2,    7),
                      ( 128,    4,    7),
                      ( 256,    8,    8),
                      ( 256,   16,    8),
                      ( 128,   32,    9),
                      ( 128,   64,    9))
  val TageNTables = TableInfo.size
19
  val UBitPeriod = 8192
L
Lingrui98 已提交
20 21 22 23 24 25 26
  val TageBanks = PredictWidth // FetchWidth

  val TotalBits = TableInfo.map {
    case (s, h, t) => {
      s * (1+t+3) * PredictWidth
    }
  }.reduce(_+_)
L
Lingrui98 已提交
27 28 29 30 31
}

abstract class TageBundle extends XSBundle with HasTageParameter
abstract class TageModule extends XSModule with HasTageParameter

L
Lingrui98 已提交
32 33 34



L
Lingrui98 已提交
35
class TageReq extends TageBundle {
L
Lingrui98 已提交
36 37 38
  val pc = UInt(VAddrBits.W)
  val hist = UInt(HistoryLength.W)
  val mask = UInt(PredictWidth.W)
L
Lingrui98 已提交
39 40 41
}

class TageResp extends TageBundle {
L
Lingrui98 已提交
42 43
  val ctr = UInt(3.W)
  val u = UInt(2.W)
L
Lingrui98 已提交
44 45 46
}

class TageUpdate extends TageBundle {
L
Lingrui98 已提交
47
  val pc = UInt(VAddrBits.W)
48
  val fetchIdx = UInt(log2Up(TageBanks).W)
L
Lingrui98 已提交
49 50 51 52 53 54 55 56 57
  val hist = UInt(HistoryLength.W)
  // update tag and ctr
  val mask = Vec(TageBanks, Bool())
  val taken = Vec(TageBanks, Bool())
  val alloc = Vec(TageBanks, Bool())
  val oldCtr = Vec(TageBanks, UInt(3.W))
  // update u
  val uMask = Vec(TageBanks, Bool())
  val u = Vec(TageBanks, UInt(2.W))
L
Lingrui98 已提交
58 59 60
}

class FakeTageTable() extends TageModule {
L
Lingrui98 已提交
61 62 63 64 65 66
  val io = IO(new Bundle() {
    val req = Input(Valid(new TageReq))
    val resp = Output(Vec(TageBanks, Valid(new TageResp)))
    val update = Input(new TageUpdate)
  })
  io.resp := DontCare
L
Lingrui98 已提交
67 68 69 70

}

class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPeriod: Int) extends TageModule {
L
Lingrui98 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
  val io = IO(new Bundle() {
    val req = Input(Valid(new TageReq))
    val resp = Output(Vec(TageBanks, Valid(new TageResp)))
    val update = Input(new TageUpdate)
  })

  // bypass entries for tage update
  val wrBypassEntries = PredictWidth

  def compute_folded_hist(hist: UInt, l: Int) = {
    val nChunks = (histLen + l - 1) / l
    val hist_chunks = (0 until nChunks) map {i =>
      hist(min((i+1)*l, histLen)-1, i*l)
    }
    hist_chunks.reduce(_^_)
  }

  def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt) = {
    val idx_history = compute_folded_hist(hist, log2Ceil(nRows))
    val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows)-1,0)
    val tag_history = compute_folded_hist(hist, tagLen)
    // Use another part of pc to make tags
    val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history)(tagLen-1,0)
    (idx, tag)
  }

  def inc_ctr(ctr: UInt, taken: Bool): UInt = {
    Mux(!taken, Mux(ctr === 0.U, 0.U, ctr - 1.U),
                Mux(ctr === 7.U, 7.U, ctr + 1.U))
  }
101 102
  // circular shifting
  def circularShiftLeft(source: UInt, len: Int, shamt: UInt): UInt = {
L
Lingrui98 已提交
103
    val res = Wire(UInt(len.W))
104 105
    val higher = source << shamt
    val lower = source >> (len.U - shamt)
L
Lingrui98 已提交
106 107 108 109
    res := higher | lower
    res
  }

L
Lingrui98 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122
  val doing_reset = RegInit(true.B)
  val reset_idx = RegInit(0.U(log2Ceil(nRows).W))
  reset_idx := reset_idx + doing_reset
  when (reset_idx === (nRows-1).U) { doing_reset := false.B }

  class TageEntry() extends TageBundle {
    val valid = Bool()
    val tag = UInt(tagLen.W)
    val ctr = UInt(3.W)
  }

  val tageEntrySz = 1 + tagLen + 3

L
Lingrui98 已提交
123
  // use real address to index
124 125
  // val unhashed_idxes = VecInit((0 until TageBanks).map(b => ((io.req.bits.pc >> 1.U) + b.U) >> log2Up(TageBanks).U))
  val unhashed_idx = io.req.bits.pc >> 1.U
L
Lingrui98 已提交
126

127 128 129 130
  // val idxes_and_tags = (0 until TageBanks).map(b => compute_tag_and_hash(unhashed_idxes(b.U), io.req.bits.hist))
  val (idx, tag) = compute_tag_and_hash(unhashed_idx, io.req.bits.hist)
  // val idxes = VecInit(idxes_and_tags.map(_._1))
  // val tags = VecInit(idxes_and_tags.map(_._2))
L
Lingrui98 已提交
131

132 133
  val idxLatch = RegEnable(idx, enable=io.req.valid)
  val tagLatch = RegEnable(tag, enable=io.req.valid)
L
Lingrui98 已提交
134 135 136 137 138

  val hi_us = List.fill(TageBanks)(Module(new SRAMTemplate(Bool(), set=nRows, shouldReset=false, holdRead=true, singlePort=false)))
  val lo_us = List.fill(TageBanks)(Module(new SRAMTemplate(Bool(), set=nRows, shouldReset=false, holdRead=true, singlePort=false)))
  val table = List.fill(TageBanks)(Module(new SRAMTemplate(new TageEntry, set=nRows, shouldReset=false, holdRead=true, singlePort=false)))

L
Lingrui98 已提交
139 140 141
  val hi_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
  val lo_us_r = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
  val table_r = WireInit(0.U.asTypeOf(Vec(TageBanks, new TageEntry)))
L
Lingrui98 已提交
142

L
Lingrui98 已提交
143
  val baseBank = io.req.bits.pc(log2Up(TageBanks), 1)
144
  val baseBankLatch = RegEnable(baseBank, enable=io.req.valid)
L
Lingrui98 已提交
145

L
Lingrui98 已提交
146

L
Lingrui98 已提交
147 148 149 150 151
  // This is different from that in BTB and BIM
  // We want to pass the correct index and tag into the TAGE table
  // if baseBank == 9, then we want to pass idxes_and_tags(0) to bank 9,
  //                         0  1        8  9  10      15
  // so the correct order is 7, 8, ..., 15, 0,  1, ..., 6
152 153 154
  // val iAndTIdxInOrder = VecInit((0 until TageBanks).map(b => ((TageBanks.U +& b.U) - baseBank)(log2Up(TageBanks)-1, 0)))
  // val iAndTIdxInOrderLatch = RegEnable(iAndTIdxInOrder, enable=io.req.valid)
  val bankIdxInOrder = VecInit((0 until TageBanks).map(b => (baseBankLatch +& b.U)(log2Up(TageBanks)-1, 0)))
L
Lingrui98 已提交
155

L
Lingrui98 已提交
156
  val realMask = circularShiftLeft(io.req.bits.mask, TageBanks, baseBank)
L
Lingrui98 已提交
157
  val maskLatch = RegEnable(io.req.bits.mask, enable=io.req.valid)
L
Lingrui98 已提交
158

L
Lingrui98 已提交
159 160
  (0 until TageBanks).map(
    b => {
L
Lingrui98 已提交
161 162 163
      hi_us(b).reset := reset.asBool
      lo_us(b).reset := reset.asBool
      table(b).reset := reset.asBool
L
Lingrui98 已提交
164 165 166
      hi_us(b).io.r.req.valid := io.req.valid && realMask(b)
      lo_us(b).io.r.req.valid := io.req.valid && realMask(b)
      table(b).io.r.req.valid := io.req.valid && realMask(b)
167 168 169
      lo_us(b).io.r.req.bits.setIdx := idx
      hi_us(b).io.r.req.bits.setIdx := idx
      table(b).io.r.req.bits.setIdx := idx
L
Lingrui98 已提交
170 171

      // Reorder done
172 173 174 175 176 177
      // hi_us_r(b) := hi_us(bankIdxInOrder(b)).io.r.resp.data(0)
      // lo_us_r(b) := lo_us(bankIdxInOrder(b)).io.r.resp.data(0)
      // table_r(b) := table(bankIdxInOrder(b)).io.r.resp.data(0)
      hi_us_r(b) := hi_us(b).io.r.resp.data(0)
      lo_us_r(b) := lo_us(b).io.r.resp.data(0)
      table_r(b) := table(b).io.r.resp.data(0)
L
Lingrui98 已提交
178 179 180
    }
  )

181
  val req_rhits = VecInit((0 until TageBanks).map(b => table_r(bankIdxInOrder(b)).valid && table_r(bankIdxInOrder(b)).tag === tagLatch))
L
Lingrui98 已提交
182 183

  (0 until TageBanks).map(b => {
L
Lingrui98 已提交
184
    io.resp(b).valid := req_rhits(b) && maskLatch(b)
185 186
    io.resp(b).bits.ctr := table_r(bankIdxInOrder(b)).ctr
    io.resp(b).bits.u := Cat(hi_us_r(bankIdxInOrder(b)),lo_us_r(bankIdxInOrder(b)))
L
Lingrui98 已提交
187 188 189 190 191 192 193 194 195 196 197
  })


  val clear_u_ctr = RegInit(0.U((log2Ceil(uBitPeriod) + log2Ceil(nRows) + 1).W))
  when (doing_reset) { clear_u_ctr := 1.U } .otherwise { clear_u_ctr := clear_u_ctr + 1.U }

  val doing_clear_u = clear_u_ctr(log2Ceil(uBitPeriod)-1,0) === 0.U
  val doing_clear_u_hi = doing_clear_u && clear_u_ctr(log2Ceil(uBitPeriod) + log2Ceil(nRows)) === 1.U
  val doing_clear_u_lo = doing_clear_u && clear_u_ctr(log2Ceil(uBitPeriod) + log2Ceil(nRows)) === 0.U
  val clear_u_idx = clear_u_ctr >> log2Ceil(uBitPeriod)

198 199
  // Use fetchpc to compute hash
  val (update_idx, update_tag) = compute_tag_and_hash((io.update.pc >> 1.U) - io.update.fetchIdx, io.update.hist)
L
Lingrui98 已提交
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

  val update_wdata = Wire(Vec(TageBanks, new TageEntry))


  (0 until TageBanks).map(b => {
    table(b).io.w.req.valid := io.update.mask(b) || doing_reset
    table(b).io.w.req.bits.setIdx := Mux(doing_reset, reset_idx, update_idx)
    table(b).io.w.req.bits.data := Mux(doing_reset, 0.U.asTypeOf(new TageEntry), update_wdata(b))
  })

  val update_hi_wdata = Wire(Vec(TageBanks, Bool()))
  (0 until TageBanks).map(b => {
    hi_us(b).io.w.req.valid := io.update.uMask(b) || doing_reset || doing_clear_u_hi
    hi_us(b).io.w.req.bits.setIdx := Mux(doing_reset, reset_idx, Mux(doing_clear_u_hi, clear_u_idx, update_idx))
    hi_us(b).io.w.req.bits.data := Mux(doing_reset || doing_clear_u_hi, 0.U, update_hi_wdata(b))
  })

  val update_lo_wdata = Wire(Vec(TageBanks, Bool()))
  (0 until TageBanks).map(b => {
    lo_us(b).io.w.req.valid := io.update.uMask(b) || doing_reset || doing_clear_u_lo
    lo_us(b).io.w.req.bits.setIdx := Mux(doing_reset, reset_idx, Mux(doing_clear_u_lo, clear_u_idx, update_idx))
    lo_us(b).io.w.req.bits.data := Mux(doing_reset || doing_clear_u_lo, 0.U, update_lo_wdata(b))
  })

  val wrbypass_tags    = Reg(Vec(wrBypassEntries, UInt(tagLen.W)))
  val wrbypass_idxs    = Reg(Vec(wrBypassEntries, UInt(log2Ceil(nRows).W)))
226 227
  val wrbypass_us      = Reg(Vec(wrBypassEntries, Vec(TageBanks, UInt(2.W))))
  val wrbypass_ctrs    = Reg(Vec(wrBypassEntries, Vec(TageBanks, UInt(3.W))))
L
Lingrui98 已提交
228 229 230 231 232 233 234
  val wrbypass_enq_idx = RegInit(0.U(log2Ceil(wrBypassEntries).W))

  val wrbypass_hits    = VecInit((0 until wrBypassEntries) map { i =>
    !doing_reset &&
    wrbypass_tags(i) === update_tag &&
    wrbypass_idxs(i) === update_idx
  })
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
  val wrbypass_rhits   = VecInit((0 until wrBypassEntries) map { i =>
    io.req.valid &&
    wrbypass_tags(i) === tag &&
    wrbypass_idxs(i) === idx
  })
  val wrbypass_hit      = wrbypass_hits.reduce(_||_)
  val wrbypass_rhit     = wrbypass_rhits.reduce(_||_)
  val wrbypass_hit_idx  = PriorityEncoder(wrbypass_hits)
  val wrbypass_rhit_idx = PriorityEncoder(wrbypass_rhits)

  val wrbypass_rhit_latch = RegNext(wrbypass_rhit)
  val hit_ctrs = RegEnable(wrbypass_ctrs(wrbypass_rhit_idx), wrbypass_hit)
  // when (wrbypass_rhit_latch) {

  // }

L
Lingrui98 已提交
251 252 253 254 255 256

  for (w <- 0 until TageBanks) {
    update_wdata(w).ctr   := Mux(io.update.alloc(w),
      Mux(io.update.taken(w), 4.U,
                              3.U
      ),
257 258 259 260
      // Mux(wrbypass_hit,       inc_ctr(wrbypass_ctrs(wrbypass_hit_idx)(w), io.update.taken(w)),
      //                         inc_ctr(io.update.oldCtr(w), io.update.taken(w))
      // )
      inc_ctr(io.update.oldCtr(w), io.update.taken(w))
L
Lingrui98 已提交
261 262 263 264 265 266 267 268 269 270
    )
    update_wdata(w).valid := true.B
    update_wdata(w).tag   := update_tag

    update_hi_wdata(w)    := io.update.u(w)(1)
    update_lo_wdata(w)    := io.update.u(w)(0)
  }

  when (io.update.mask.reduce(_||_)) {
    when (wrbypass_hits.reduce(_||_)) {
271
      wrbypass_ctrs(wrbypass_hit_idx) := VecInit(update_wdata.map(_.ctr))
L
Lingrui98 已提交
272
    } .otherwise {
273
      wrbypass_ctrs(wrbypass_enq_idx) := VecInit(update_wdata.map(_.ctr))
L
Lingrui98 已提交
274 275 276 277 278
      wrbypass_tags(wrbypass_enq_idx) := update_tag
      wrbypass_idxs(wrbypass_enq_idx) := update_idx
      wrbypass_enq_idx := (wrbypass_enq_idx + 1.U)(log2Ceil(wrBypassEntries)-1,0)
    }
  }
279 280 281 282 283 284 285 286
  // when (io.update.uMask.reduce(_||_)) {
  //   when (wrbypass_hits.reduce(_||_)) {
  //     wrbypass_us(wrbypass_hit_idx) := VecInit(io.update.u.map(_))
  //   }
  // }
  val u = io.update
  val b = PriorityEncoder(u.mask)
  val ub = PriorityEncoder(u.uMask)
L
Lingrui98 已提交
287 288
  XSDebug(io.req.valid, "tableReq: pc=0x%x, hist=%x, idx=%d, tag=%x, baseBank=%d, mask=%b, realMask=%b\n",
    io.req.bits.pc, io.req.bits.hist, idx, tag, baseBank, io.req.bits.mask, realMask)
L
Lingrui98 已提交
289
  for (i <- 0 until TageBanks) {
L
Lingrui98 已提交
290
    XSDebug(RegNext(io.req.valid) && req_rhits(i), "TageTableResp[%d]: idx=%d, hit:%d, ctr:%d, u:%d\n", i.U, idxLatch, req_rhits(i), io.resp(i).bits.ctr, io.resp(i).bits.u)
L
Lingrui98 已提交
291
  }
L
Lingrui98 已提交
292 293

  XSDebug(RegNext(io.req.valid), "TageTableResp: hits:%b, maskLatch is %b\n", req_rhits.asUInt, maskLatch)
294 295 296 297
  XSDebug(RegNext(io.req.valid) && !req_rhits.reduce(_||_), "TageTableResp: no hits!\n")

  XSDebug(io.update.mask.reduce(_||_), "update Table: pc:%x, fetchIdx:%d, hist:%x, bank:%d, taken:%d, alloc:%d, oldCtr:%d\n",
    u.pc, u.fetchIdx, u.hist, b, u.taken(b), u.alloc(b), u.oldCtr(b))
298 299
  XSDebug(io.update.mask.reduce(_||_), "update Table: writing tag:%b, ctr%d in idx:%d\n",
    update_wdata(b).tag, update_wdata(b).ctr, update_idx)
300 301 302 303 304
  XSDebug(io.update.mask.reduce(_||_), "update u: pc:%x, fetchIdx:%d, hist:%x, bank:%d, writing in u:%b\n",
    u.pc, u.fetchIdx, u.hist, ub, io.update.u(ub))

  // XSDebug(wrbypass_hits.reduce(_||_), "wrbypass hits, wridx:%d, tag:%x, ctr:%d, idx:%d\n",
  //   wrbypass_hit_idx, )
305 306 307 308 309
  // for (b <- 0 until TageBanks) {
  //   for (i <- 0 until nRows) {
  //     val r = ReadAndHold(array, io.r.req.bits.setIdx, realRen)
  //   }
  // }
L
Lingrui98 已提交
310 311
}

312
abstract class BaseTage extends BasePredictor with HasTageParameter {
L
Lingrui98 已提交
313
  class TAGEResp extends Resp {
314 315
    val takens = Vec(PredictWidth, Bool())
    val hits = Vec(PredictWidth, Bool())
L
Lingrui98 已提交
316
  }
317
  class TAGEMeta extends Meta{
L
Lingrui98 已提交
318 319 320 321 322 323
  }
  class FromBIM extends FromOthers {
    val ctrs = Vec(PredictWidth, UInt(2.W))
  }
  class TageIO extends DefaultBasePredictorIO {
    val resp = Output(new TAGEResp)
L
Lingrui98 已提交
324
    val meta = Output(Vec(PredictWidth, new TageMeta))
L
Lingrui98 已提交
325 326 327 328
    val bim = Input(new FromBIM)
    val s3Fire = Input(Bool())
  }

L
Lingrui98 已提交
329
  override val io = IO(new TageIO)
330
}
L
Lingrui98 已提交
331

332
class FakeTage extends BaseTage {
L
Lingrui98 已提交
333 334
  io.resp <> DontCare
  io.meta <> DontCare
L
Lingrui98 已提交
335 336 337
}


338
class Tage extends BaseTage {
L
Lingrui98 已提交
339 340 341 342

  val tables = TableInfo.map {
    case (nRows, histLen, tagLen) => {
      val t = if(EnableBPD) Module(new TageTable(nRows, histLen, tagLen, UBitPeriod)) else Module(new FakeTageTable)
343
      t.io.req.valid := io.pc.valid && !io.flush
L
Lingrui98 已提交
344 345 346 347 348 349 350 351
      t.io.req.bits.pc := io.pc.bits
      t.io.req.bits.hist := io.hist
      t.io.req.bits.mask := io.inMask
      t
    }
  }

  // Keep the table responses to process in s3
L
Lingrui98 已提交
352
  val resps = VecInit(tables.map(t => RegEnable(t.io.resp, enable=io.s3Fire)))
L
Lingrui98 已提交
353
  // val flushLatch = RegNext(io.flush)
L
Lingrui98 已提交
354 355 356 357 358 359 360

  val s2_bim = RegEnable(io.bim, enable=io.pc.valid) // actually it is s2Fire
  val s3_bim = RegEnable(s2_bim, enable=io.s3Fire)

  val debug_pc_s2 = RegEnable(io.pc.bits, enable=io.pc.valid)
  val debug_pc_s3 = RegEnable(debug_pc_s2, enable=io.s3Fire)

361 362 363
  val debug_hist_s2 = RegEnable(io.hist, enable=io.pc.valid)
  val debug_hist_s3 = RegEnable(debug_hist_s2, enable=io.s3Fire)

L
Lingrui98 已提交
364 365 366 367 368 369
  val u = io.update.bits.ui
  val updateValid = io.update.valid
  val updateHist = io.update.bits.hist

  val updateMeta = u.brInfo.tageMeta
  val updateMisPred = u.isMisPred && u.pd.isBr
L
Lingrui98 已提交
370 371 372 373 374 375 376 377 378 379 380 381

  val updateMask = WireInit(0.U.asTypeOf(Vec(TageNTables, Vec(TageBanks, Bool()))))
  val updateUMask = WireInit(0.U.asTypeOf(Vec(TageNTables, Vec(TageBanks, Bool()))))
  val updateTaken = Wire(Vec(TageNTables, Vec(TageBanks, Bool())))
  val updateAlloc = Wire(Vec(TageNTables, Vec(TageBanks, Bool())))
  val updateOldCtr = Wire(Vec(TageNTables, Vec(TageBanks, UInt(3.W))))
  val updateU = Wire(Vec(TageNTables, Vec(TageBanks, UInt(2.W))))
  updateTaken := DontCare
  updateAlloc := DontCare
  updateOldCtr := DontCare
  updateU := DontCare

382
  val updateBank = u.pc(log2Ceil(TageBanks), 1)
L
Lingrui98 已提交
383 384 385 386 387 388 389

  // access tag tables and output meta info
  for (w <- 0 until TageBanks) {
    var altPred = s3_bim.ctrs(w)(1)
    val finalAltPred = WireInit(s3_bim.ctrs(w)(1))
    var provided = false.B
    var provider = 0.U
L
Lingrui98 已提交
390
    io.resp.takens(w) := s3_bim.ctrs(w)(1)
L
Lingrui98 已提交
391 392

    for (i <- 0 until TageNTables) {
L
Lingrui98 已提交
393
      val hit = resps(i)(w).valid
L
Lingrui98 已提交
394 395
      val ctr = resps(i)(w).bits.ctr
      when (hit) {
L
Lingrui98 已提交
396
        io.resp.takens(w) := Mux(ctr === 3.U || ctr === 4.U, altPred, ctr(2)) // Use altpred on weak taken
L
Lingrui98 已提交
397 398 399 400 401 402
        finalAltPred := altPred
      }
      provided = provided || hit          // Once hit then provide
      provider = Mux(hit, i.U, provider)  // Use the last hit as provider
      altPred = Mux(hit, ctr(2), altPred) // Save current pred as potential altpred
    }
L
Lingrui98 已提交
403
    io.resp.hits(w) := provided
L
Lingrui98 已提交
404 405
    io.meta(w).provider.valid := provided
    io.meta(w).provider.bits := provider
L
Lingrui98 已提交
406
    io.meta(w).altDiffers := finalAltPred =/= io.resp.takens(w)
L
Lingrui98 已提交
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
    io.meta(w).providerU := resps(provider)(w).bits.u
    io.meta(w).providerCtr := resps(provider)(w).bits.ctr

    // Create a mask fo tables which did not hit our query, and also contain useless entries
    // and also uses a longer history than the provider
    val allocatableSlots = (VecInit(resps.map(r => !r(w).valid && r(w).bits.u === 0.U)).asUInt &
      ~(LowerMask(UIntToOH(provider), TageNTables) & Fill(TageNTables, provided.asUInt))
    )
    val allocLFSR = LFSR64()(TageNTables - 1, 0)
    val firstEntry = PriorityEncoder(allocatableSlots)
    val maskedEntry = PriorityEncoder(allocatableSlots & allocLFSR)
    val allocEntry = Mux(allocatableSlots(maskedEntry), maskedEntry, firstEntry)
    io.meta(w).allocate.valid := allocatableSlots =/= 0.U
    io.meta(w).allocate.bits := allocEntry

L
Lingrui98 已提交
422 423 424 425

    val isUpdateTaken = updateValid && updateBank === w.U &&
      u.taken && u.pd.isBr
    when (u.pd.isBr && updateValid && updateBank === w.U) {
L
Lingrui98 已提交
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
      when (updateMeta.provider.valid) {
        val provider = updateMeta.provider.bits

        updateMask(provider)(w) := true.B
        updateUMask(provider)(w) := true.B

        updateU(provider)(w) := Mux(!updateMeta.altDiffers, updateMeta.providerU,
          Mux(updateMisPred, Mux(updateMeta.providerU === 0.U, 0.U, updateMeta.providerU - 1.U),
                              Mux(updateMeta.providerU === 3.U, 3.U, updateMeta.providerU + 1.U))
        )
        updateTaken(provider)(w) := isUpdateTaken
        updateOldCtr(provider)(w) := updateMeta.providerCtr
        updateAlloc(provider)(w) := false.B
      }
    }
  }

L
Lingrui98 已提交
443
  when (updateValid && updateMisPred) {
L
Lingrui98 已提交
444 445 446 447
    val idx = updateBank
    val allocate = updateMeta.allocate
    when (allocate.valid) {
      updateMask(allocate.bits)(idx) := true.B
L
Lingrui98 已提交
448
      updateTaken(allocate.bits)(idx) := u.taken
L
Lingrui98 已提交
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
      updateAlloc(allocate.bits)(idx) := true.B
      updateUMask(allocate.bits)(idx) := true.B
      updateU(allocate.bits)(idx) := 0.U
    }.otherwise {
      val provider = updateMeta.provider
      val decrMask = Mux(provider.valid, ~LowerMask(UIntToOH(provider.bits), TageNTables), 0.U)
      for (i <- 0 until TageNTables) {
        when (decrMask(i)) {
          updateUMask(i)(idx) := true.B
          updateU(i)(idx) := 0.U
        }
      }
    }
  }

  for (i <- 0 until TageNTables) {
    for (w <- 0 until TageBanks) {
      tables(i).io.update.mask(w) := updateMask(i)(w)
      tables(i).io.update.taken(w) := updateTaken(i)(w)
      tables(i).io.update.alloc(w) := updateAlloc(i)(w)
      tables(i).io.update.oldCtr(w) := updateOldCtr(i)(w)

      tables(i).io.update.uMask(w) := updateUMask(i)(w)
      tables(i).io.update.u(w) := updateU(i)(w)
    }
    // use fetch pc instead of instruction pc
L
Lingrui98 已提交
475 476
    tables(i).io.update.pc := u.pc
    tables(i).io.update.hist := updateHist
477
    tables(i).io.update.fetchIdx := u.brInfo.fetchIdx
L
Lingrui98 已提交
478 479 480 481 482
  }



  val m = updateMeta
483 484
  val bri = u.brInfo
  XSDebug(io.pc.valid, "req: pc=0x%x, hist=%x\n", io.pc.bits, io.hist)
485 486 487
  XSDebug(io.s3Fire, "s3Fire:%d, resp: pc=%x, hist=%x\n", io.s3Fire, debug_pc_s2, debug_hist_s2)
  XSDebug(RegNext(io.s3Fire), "s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n",
    debug_pc_s3, debug_hist_s3, io.resp.hits.asUInt, io.resp.takens.asUInt)
L
Lingrui98 已提交
488 489 490
  for (i <- 0 until TageNTables) {
    XSDebug(RegNext(io.s3Fire), "Table(%d): valids:%b, resp_ctrs:%b, resp_us:%b\n", i.U, VecInit(resps(i).map(_.valid)).asUInt, Cat(resps(i).map(_.bits.ctr)), Cat(resps(i).map(_.bits.u)))
  }
491 492
  XSDebug(io.update.valid, "update: pc=%x, fetchpc=%x, cycle=%d, hist=%x, taken:%d, misPred:%d, histPtr:%d, bimctr:%d, pvdr(%d):%d, altDiff:%d, pvdrU:%d, pvdrCtr:%d, alloc(%d):%d\n",
    u.pc, u.pc - (bri.fetchIdx << 1.U), bri.debug_tage_cycle,  updateHist, u.taken, u.isMisPred, bri.histPtr, bri.bimCtr, m.provider.valid, m.provider.bits, m.altDiffers, m.providerU, m.providerCtr, m.allocate.valid, m.allocate.bits)
L
Lingrui98 已提交
493
}