Tage.scala 16.2 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 19 20 21 22 23 24 25 26
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
  val UBitPeriod = 2048
  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 48 49 50 51 52 53 54 55 56
  val pc = UInt(VAddrBits.W)
  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 已提交
57 58 59
}

class FakeTageTable() extends TageModule {
L
Lingrui98 已提交
60 61 62 63 64 65
  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 已提交
66 67 68 69

}

class TageTable(val nRows: Int, val histLen: Int, val tagLen: Int, val uBitPeriod: Int) extends TageModule {
L
Lingrui98 已提交
70 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))
  }

L
Lingrui98 已提交
101 102 103 104 105 106 107 108
  def circularShiftRight(source: UInt, len: Int, shamt: UInt): UInt = {
    val res = Wire(UInt(len.W))
    val higher = source << (len.U - shamt)
    val lower = source >> shamt
    res := higher | lower
    res
  }

L
Lingrui98 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121
  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 已提交
122 123
  // use real address to index
  val unhashed_idxes = VecInit((0 until TageBanks).map(b => ((io.req.bits.pc >> 1.U) + b.U) >> log2Up(TageBanks).U))
L
Lingrui98 已提交
124

L
Lingrui98 已提交
125
  val idxes_and_tags = (0 until TageBanks).map(b => compute_tag_and_hash(unhashed_idxes(b.U), io.req.bits.hist))
L
Lingrui98 已提交
126 127
  val idxes = VecInit(idxes_and_tags.map(_._1))
  val tags = VecInit(idxes_and_tags.map(_._2))
L
Lingrui98 已提交
128

L
Lingrui98 已提交
129 130
  val idxLatch = RegEnable(idxes, enable=io.req.valid)
  val tagLatch = RegEnable(tags, enable=io.req.valid)
L
Lingrui98 已提交
131 132 133 134 135 136 137 138 139

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

  val hi_us_r = Wire(Vec(TageBanks, Bool()))
  val lo_us_r = Wire(Vec(TageBanks, Bool()))
  val table_r = Wire(Vec(TageBanks, new TageEntry))

L
Lingrui98 已提交
140 141
  val baseBank = io.req.bits.pc(log2Up(TageBanks), 1)

L
Lingrui98 已提交
142

L
Lingrui98 已提交
143 144 145 146 147 148 149
  // 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
  val iAndTIdxInOrder = VecInit((0 until TageBanks).map(b => ((TageBanks.U - baseBank) + b.U)(log2Up(TageBanks)-1, 0)))
  val iAndTIdxInOrderLatch = RegEnable(iAndTIdxInOrder, enable=io.req.valid)
L
Lingrui98 已提交
150

L
Lingrui98 已提交
151
  val realMask = circularShiftRight(io.req.bits.mask, TageBanks, baseBank)
L
Lingrui98 已提交
152

L
Lingrui98 已提交
153 154
  (0 until TageBanks).map(
    b => {
L
Lingrui98 已提交
155 156 157 158 159 160
      hi_us(b).reset := reset.asBool
      lo_us(b).reset := reset.asBool
      table(b).reset := reset.asBool
      hi_us(b).io.r.req.valid := io.req.valid
      lo_us(b).io.r.req.valid := io.req.valid
      table(b).io.r.req.valid := io.req.valid
L
Lingrui98 已提交
161 162 163
      lo_us(b).io.r.req.bits.setIdx := idxes(iAndTIdxInOrder(b.U))
      hi_us(b).io.r.req.bits.setIdx := idxes(iAndTIdxInOrder(b.U))
      table(b).io.r.req.bits.setIdx := idxes(iAndTIdxInOrder(b.U))
L
Lingrui98 已提交
164 165

      // Reorder done
L
Lingrui98 已提交
166 167 168
      hi_us_r(iAndTIdxInOrderLatch(b)) := hi_us(b).io.r.resp.data(0)
      lo_us_r(iAndTIdxInOrderLatch(b)) := lo_us(b).io.r.resp.data(0)
      table_r(iAndTIdxInOrderLatch(b)) := table(b).io.r.resp.data(0)
L
Lingrui98 已提交
169 170 171
    }
  )

L
Lingrui98 已提交
172
  val req_rhits = VecInit((0 until TageBanks).map(b => table_r(b).valid && table_r(b).tag === tagLatch(b)))
L
Lingrui98 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

  (0 until TageBanks).map(b => {
    io.resp(b).valid := req_rhits(b)
    io.resp(b).bits.ctr := table_r(b).ctr
    io.resp(b).bits.u := Cat(hi_us_r(b),lo_us_r(b))
  })


  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)

L
Lingrui98 已提交
189
  val (update_idx, update_tag) = compute_tag_and_hash(io.update.pc >> (1.U + log2Up(TageBanks).U), io.update.hist)
L
Lingrui98 已提交
190 191 192 193 194 195 196 197 198 199 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 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253

  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)))
  val wrbypass         = Reg(Vec(wrBypassEntries, Vec(TageBanks, UInt(3.W))))
  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
  })
  val wrbypass_hit     = wrbypass_hits.reduce(_||_)
  val wrbypass_hit_idx = PriorityEncoder(wrbypass_hits)

  for (w <- 0 until TageBanks) {
    update_wdata(w).ctr   := Mux(io.update.alloc(w),
      Mux(io.update.taken(w), 4.U,
                              3.U
      ),
      Mux(wrbypass_hit,       inc_ctr(wrbypass(wrbypass_hit_idx)(w), io.update.taken(w)),
                              inc_ctr(io.update.oldCtr(w), io.update.taken(w))
      )
    )
    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(_||_)) {
      wrbypass(wrbypass_hit_idx) := VecInit(update_wdata.map(_.ctr))
    } .otherwise {
      wrbypass     (wrbypass_enq_idx) := VecInit(update_wdata.map(_.ctr))
      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)
    }
  }
  XSDebug(io.req.valid, "tableReq: pc=0x%x, hist=%b, base_idx=%d, base_tag=%x\n",
L
Lingrui98 已提交
254
    io.req.bits.pc, io.req.bits.hist, idxes(0.U), tags(0.U))
L
Lingrui98 已提交
255
  for (i <- 0 until TageBanks) {
L
Lingrui98 已提交
256
    XSDebug(RegNext(io.req.valid), "TageTableResp[%d]: idx=%d, hit:%d, ctr:%d, u:%d\n", i.U, idxLatch(i), req_rhits(i), table_r(i).ctr, Cat(hi_us_r(i),lo_us_r(i)).asUInt)
L
Lingrui98 已提交
257
  }
L
Lingrui98 已提交
258 259 260

}

L
Lingrui98 已提交
261
class FakeTAGE extends BasePredictor with HasTageParameter {
L
Lingrui98 已提交
262 263 264
  class TAGEResp extends Resp {
    val takens = Vec(PredictWidth, ValidUndirectioned(Bool()))
  }
L
Lingrui98 已提交
265
  class TAGEMeta extends Meta {
L
Lingrui98 已提交
266 267 268 269 270 271
  }
  class FromBIM extends FromOthers {
    val ctrs = Vec(PredictWidth, UInt(2.W))
  }
  class TageIO extends DefaultBasePredictorIO {
    val resp = Output(new TAGEResp)
L
Lingrui98 已提交
272
    val meta = Output(Vec(PredictWidth, new TageMeta))
L
Lingrui98 已提交
273 274 275 276
    val bim = Input(new FromBIM)
    val s3Fire = Input(Bool())
  }

L
Lingrui98 已提交
277
  override val io = IO(new TageIO)
L
Lingrui98 已提交
278

L
Lingrui98 已提交
279 280
  io.resp <> DontCare
  io.meta <> DontCare
L
Lingrui98 已提交
281 282 283
}


L
Lingrui98 已提交
284
class Tage extends BasePredictor with HasTageParameter {
L
Lingrui98 已提交
285 286 287
  class TAGEResp extends Resp {
    val takens = Vec(PredictWidth, ValidUndirectioned(Bool()))
  }
L
Lingrui98 已提交
288
  class TAGEMeta extends Meta{
L
Lingrui98 已提交
289 290 291 292 293 294
  }
  class FromBIM extends FromOthers {
    val ctrs = Vec(PredictWidth, UInt(2.W))
  }
  class TageIO extends DefaultBasePredictorIO {
    val resp = Output(new TAGEResp)
L
Lingrui98 已提交
295
    val meta = Output(Vec(PredictWidth, new TageMeta))
L
Lingrui98 已提交
296 297 298 299
    val bim = Input(new FromBIM)
    val s3Fire = Input(Bool())
  }

L
Lingrui98 已提交
300
  override val io = IO(new TageIO)
L
Lingrui98 已提交
301 302 303 304 305 306 307 308 309 310 311 312 313

  val tables = TableInfo.map {
    case (nRows, histLen, tagLen) => {
      val t = if(EnableBPD) Module(new TageTable(nRows, histLen, tagLen, UBitPeriod)) else Module(new FakeTageTable)
      t.io.req.valid := io.pc.valid
      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 已提交
314
  val resps = VecInit(tables.map(t => RegEnable(t.io.resp, enable=io.s3Fire)))
L
Lingrui98 已提交
315 316 317 318 319 320 321

  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)

L
Lingrui98 已提交
322 323
  val updateMeta = io.update.bits.brInfo.tageMeta
  val updateMisPred = io.update.bits.isMisPred && io.update.bits.pd.isBr
L
Lingrui98 已提交
324 325 326 327 328 329 330 331 332 333 334 335

  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

L
Lingrui98 已提交
336
  val updateBank = io.update.bits.pc >> 1.U
L
Lingrui98 已提交
337 338 339 340 341 342 343 344 345 346 347

  // 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
    io.resp.takens(w).valid := false.B
    io.resp.takens(w).bits := s3_bim.ctrs(w)(1)

    for (i <- 0 until TageNTables) {
L
Lingrui98 已提交
348 349
      val hit = resps(i)(w).valid
      io.resp.takens(w).valid := hit
L
Lingrui98 已提交
350 351 352 353 354 355 356 357 358 359 360 361
      val ctr = resps(i)(w).bits.ctr
      when (hit) {
        io.resp.takens(w).bits := Mux(ctr === 3.U || ctr === 4.U, altPred, ctr(2)) // Use altpred on weak taken
        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
    }
    io.resp.takens(w).valid := provided
    io.meta(w).provider.valid := provided
    io.meta(w).provider.bits := provider
L
Lingrui98 已提交
362
    io.meta(w).altDiffers := finalAltPred =/= io.resp.takens(w).bits
L
Lingrui98 已提交
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
    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

    val isUpdateTaken = io.update.valid && updateBank === w.U &&
L
Lingrui98 已提交
379 380
      io.update.bits.taken && io.update.bits.pd.isBr
    when (io.update.bits.pd.isBr && io.update.valid && updateBank === w.U) {
L
Lingrui98 已提交
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
      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
      }
    }
  }

  when (io.update.valid && updateMisPred) {
    val idx = updateBank
    val allocate = updateMeta.allocate
    when (allocate.valid) {
      updateMask(allocate.bits)(idx) := true.B
L
Lingrui98 已提交
403
      updateTaken(allocate.bits)(idx) := io.update.bits.taken
L
Lingrui98 已提交
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
      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 已提交
430 431
    tables(i).io.update.pc := io.update.bits.pc
    tables(i).io.update.hist := io.update.bits.hist
L
Lingrui98 已提交
432 433 434 435 436
  }



  val m = updateMeta
L
Lingrui98 已提交
437
  XSDebug(io.pc.valid, "req: pc=0x%x, hist=%b\n", io.pc.bits, io.hist)
L
Lingrui98 已提交
438 439 440 441
  XSDebug(io.update.valid, "redirect: provider(%d):%d, altDiffers:%d, providerU:%d, providerCtr:%d, allocate(%d):%d\n",
    m.provider.valid, m.provider.bits, m.altDiffers, m.providerU, m.providerCtr, m.allocate.valid, m.allocate.bits)
  // This is not reversed
  XSDebug(true.B, "s3Fire:%d, resp: pc=%x, hits=%b, takens=%b\n",
L
Lingrui98 已提交
442
    debug_pc_s3, Cat(io.resp.takens.map(_.valid)).asUInt, Cat(io.resp.takens.map(_.bits)).asUInt)
L
Lingrui98 已提交
443
}