xref: /XiangShan/src/main/scala/xiangshan/frontend/FrontendBundle.scala (revision 7052722fe6b20ae8f36e9d1d0107febde0e79dec)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16package xiangshan.frontend
17
18import chipsalliance.rocketchip.config.Parameters
19import chisel3._
20import chisel3.util._
21import chisel3.experimental.chiselName
22import xiangshan._
23import utils._
24import scala.math._
25
26@chiselName
27class FetchRequestBundle(implicit p: Parameters) extends XSBundle {
28  val startAddr       = UInt(VAddrBits.W)
29  val fallThruAddr    = UInt(VAddrBits.W)
30  val fallThruError   = Bool()
31  val ftqIdx          = new FtqPtr
32  val ftqOffset       = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))
33  val target          = UInt(VAddrBits.W)
34  val oversize        = Bool()
35
36  def fromFtqPcBundle(b: Ftq_RF_Components) = {
37    val ftError = b.fallThroughError()
38    this.startAddr := b.startAddr
39    this.fallThruError := ftError
40    this.fallThruAddr := Mux(ftError, b.nextRangeAddr, b.getFallThrough())
41    this.oversize := b.oversize
42    this
43  }
44  def fromBpuResp(resp: BranchPredictionBundle) = {
45    // only used to bypass, so some fields remains unchanged
46    this.startAddr := resp.pc
47    this.target := resp.target
48    this.ftqOffset := resp.genCfiIndex
49    this.fallThruAddr := resp.fallThroughAddr
50    this.oversize := resp.ftb_entry.oversize
51    this
52  }
53  override def toPrintable: Printable = {
54    p"[start] ${Hexadecimal(startAddr)} [pft] ${Hexadecimal(fallThruAddr)}" +
55      p"[tgt] ${Hexadecimal(target)} [ftqIdx] $ftqIdx [jmp] v:${ftqOffset.valid}" +
56      p" offset: ${ftqOffset.bits}\n"
57  }
58}
59
60class PredecodeWritebackBundle(implicit p:Parameters) extends XSBundle {
61  val pc           = Vec(PredictWidth, UInt(VAddrBits.W))
62  val pd           = Vec(PredictWidth, new PreDecodeInfo) // TODO: redefine Predecode
63  val ftqIdx       = new FtqPtr
64  val ftqOffset    = UInt(log2Ceil(PredictWidth).W)
65  val misOffset    = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))
66  val cfiOffset    = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))
67  val target       = UInt(VAddrBits.W)
68  val jalTarget    = UInt(VAddrBits.W)
69  val instrRange   = Vec(PredictWidth, Bool())
70}
71
72// Ftq send req to Prefetch
73class PrefetchRequest(implicit p:Parameters) extends XSBundle {
74  val target          = UInt(VAddrBits.W)
75}
76
77class FtqPrefechBundle(implicit p:Parameters) extends XSBundle {
78  val req = DecoupledIO(new PrefetchRequest)
79}
80
81class FetchToIBuffer(implicit p: Parameters) extends XSBundle {
82  val instrs    = Vec(PredictWidth, UInt(32.W))
83  val valid     = UInt(PredictWidth.W)
84  val enqEnable = UInt(PredictWidth.W)
85  val pd        = Vec(PredictWidth, new PreDecodeInfo)
86  val pc        = Vec(PredictWidth, UInt(VAddrBits.W))
87  val foldpc    = Vec(PredictWidth, UInt(MemPredPCWidth.W))
88  val ftqPtr       = new FtqPtr
89  val ftqOffset    = Vec(PredictWidth, ValidUndirectioned(UInt(log2Ceil(PredictWidth).W)))
90  val ipf          = Vec(PredictWidth, Bool())
91  val acf          = Vec(PredictWidth, Bool())
92  val crossPageIPFFix = Vec(PredictWidth, Bool())
93  val triggered    = Vec(PredictWidth, new TriggerCf)
94}
95
96// class BitWiseUInt(val width: Int, val init: UInt) extends Module {
97//   val io = IO(new Bundle {
98//     val set
99//   })
100// }
101// Move from BPU
102abstract class GlobalHistory(implicit p: Parameters) extends XSBundle with HasBPUConst {
103  def update(br_valids: Vec[Bool], real_taken_mask: Vec[Bool]): GlobalHistory
104}
105
106class ShiftingGlobalHistory(implicit p: Parameters) extends GlobalHistory {
107  val predHist = UInt(HistoryLength.W)
108
109  def update(shift: UInt, taken: Bool, hist: UInt = this.predHist): ShiftingGlobalHistory = {
110    val g = Wire(new ShiftingGlobalHistory)
111    g.predHist := (hist << shift) | taken
112    g
113  }
114
115  def update(br_valids: Vec[Bool], real_taken_mask: Vec[Bool]): ShiftingGlobalHistory = {
116    require(br_valids.length == numBr)
117    require(real_taken_mask.length == numBr)
118    val last_valid_idx = PriorityMux(
119      br_valids.reverse :+ true.B,
120      (numBr to 0 by -1).map(_.U(log2Ceil(numBr+1).W))
121    )
122    val first_taken_idx = PriorityEncoder(false.B +: real_taken_mask)
123    val smaller = Mux(last_valid_idx < first_taken_idx,
124      last_valid_idx,
125      first_taken_idx
126    )
127    val shift = smaller
128    val taken = real_taken_mask.reduce(_||_)
129    update(shift, taken, this.predHist)
130  }
131
132  // static read
133  def read(n: Int): Bool = predHist.asBools()(n)
134
135  final def === (that: ShiftingGlobalHistory): Bool = {
136    predHist === that.predHist
137  }
138
139  final def =/= (that: ShiftingGlobalHistory): Bool = !(this === that)
140}
141
142// circular global history pointer
143class CGHPtr(implicit p: Parameters) extends CircularQueuePtr[CGHPtr](
144  p => p(XSCoreParamsKey).HistoryLength
145){
146  override def cloneType = (new CGHPtr).asInstanceOf[this.type]
147}
148class CircularGlobalHistory(implicit p: Parameters) extends GlobalHistory {
149  val buffer = Vec(HistoryLength, Bool())
150  type HistPtr = UInt
151  def update(br_valids: Vec[Bool], real_taken_mask: Vec[Bool]): CircularGlobalHistory = {
152    this
153  }
154}
155
156class FoldedHistory(val len: Int, val compLen: Int, val max_update_num: Int)(implicit p: Parameters)
157  extends XSBundle with HasBPUConst {
158  require(compLen >= 1)
159  require(len > 0)
160  // require(folded_len <= len)
161  require(compLen >= max_update_num)
162  val folded_hist = UInt(compLen.W)
163
164  def info = (len, compLen)
165  def oldest_bit_to_get_from_ghr = (0 until max_update_num).map(len - _ - 1)
166  def oldest_bit_pos_in_folded = oldest_bit_to_get_from_ghr map (_ % compLen)
167  def oldest_bit_wrap_around = oldest_bit_to_get_from_ghr map (_ / compLen > 0)
168  def oldest_bit_start = oldest_bit_pos_in_folded.head
169
170  def get_oldest_bits_from_ghr(ghr: Vec[Bool], histPtr: CGHPtr) = {
171    // TODO: wrap inc for histPtr value
172    oldest_bit_to_get_from_ghr.map(i => ghr((histPtr + (i+1).U).value))
173  }
174
175  def circular_shift_left(src: UInt, shamt: Int) = {
176    val srcLen = src.getWidth
177    val src_doubled = Cat(src, src)
178    val shifted = src_doubled(srcLen*2-1-shamt, srcLen-shamt)
179    shifted
180  }
181
182
183  def update(ghr: Vec[Bool], histPtr: CGHPtr, num: Int, taken: Bool): FoldedHistory = {
184    // do xors for several bitsets at specified bits
185    def bitsets_xor(len: Int, bitsets: Seq[Seq[Tuple2[Int, Bool]]]) = {
186      val res = Wire(Vec(len, Bool()))
187      // println(f"num bitsets: ${bitsets.length}")
188      // println(f"bitsets $bitsets")
189      val resArr = Array.fill(len)(List[Bool]())
190      for (bs <- bitsets) {
191        for ((n, b) <- bs) {
192          resArr(n) = b :: resArr(n)
193        }
194      }
195      // println(f"${resArr.mkString}")
196      // println(f"histLen: ${this.len}, foldedLen: $folded_len")
197      for (i <- 0 until len) {
198        // println(f"bit[$i], ${resArr(i).mkString}")
199        if (resArr(i).length > 2) {
200          println(f"[warning] update logic of foldest history has two or more levels of xor gates! " +
201            f"histlen:${this.len}, compLen:$compLen")
202        }
203        if (resArr(i).length == 0) {
204          println(f"[error] bits $i is not assigned in folded hist update logic! histlen:${this.len}, compLen:$compLen")
205        }
206        res(i) := resArr(i).foldLeft(false.B)(_^_)
207      }
208      res.asUInt
209    }
210    val oldest_bits = get_oldest_bits_from_ghr(ghr, histPtr)
211
212    // mask off bits that do not update
213    val oldest_bits_masked = oldest_bits.zipWithIndex.map{
214      case (ob, i) => ob && (i < num).B
215    }
216    // if a bit does not wrap around, it should not be xored when it exits
217    val oldest_bits_set = (0 until max_update_num).filter(oldest_bit_wrap_around).map(i => (oldest_bit_pos_in_folded(i), oldest_bits_masked(i)))
218
219    // println(f"old bits pos ${oldest_bits_set.map(_._1)}")
220
221    // only the last bit could be 1, as we have at most one taken branch at a time
222    val newest_bits_masked = VecInit((0 until max_update_num).map(i => taken && ((i+1) == num).B)).asUInt
223    // if a bit does not wrap around, newest bits should not be xored onto it either
224    val newest_bits_set = (0 until max_update_num).map(i => (compLen-1-i, newest_bits_masked(i)))
225
226    // println(f"new bits set ${newest_bits_set.map(_._1)}")
227    //
228    val original_bits_masked = VecInit(folded_hist.asBools.zipWithIndex.map{
229      case (fb, i) => fb && !(num >= (len-i)).B
230    })
231    val original_bits_set = (0 until compLen).map(i => (i, original_bits_masked(i)))
232
233
234    // histLen too short to wrap around
235    val new_folded_hist =
236      if (len <= compLen) {
237        ((folded_hist << num) | taken)(compLen-1,0)
238        // circular_shift_left(max_update_num)(Cat(Reverse(newest_bits_masked), folded_hist(compLen-max_update_num-1,0)), num)
239      } else {
240        // do xor then shift
241        val xored = bitsets_xor(compLen, Seq(original_bits_set, oldest_bits_set, newest_bits_set))
242        circular_shift_left(xored, num)
243      }
244    val fh = WireInit(this)
245    fh.folded_hist := new_folded_hist
246    fh
247  }
248
249  // def update(ghr: Vec[Bool], histPtr: CGHPtr, valids: Vec[Bool], takens: Vec[Bool]): FoldedHistory = {
250  //   val fh = WireInit(this)
251  //   require(valids.length == max_update_num)
252  //   require(takens.length == max_update_num)
253  //   val last_valid_idx = PriorityMux(
254  //     valids.reverse :+ true.B,
255  //     (max_update_num to 0 by -1).map(_.U(log2Ceil(max_update_num+1).W))
256  //     )
257  //   val first_taken_idx = PriorityEncoder(false.B +: takens)
258  //   val smaller = Mux(last_valid_idx < first_taken_idx,
259  //     last_valid_idx,
260  //     first_taken_idx
261  //   )
262  //   // update folded_hist
263  //   fh.update(ghr, histPtr, smaller, takens.reduce(_||_))
264  // }
265  // println(f"folded hist original length: ${len}, folded len: ${folded_len} " +
266  //   f"oldest bits' pos in folded: ${oldest_bit_pos_in_folded}")
267
268
269}
270
271class TableAddr(val idxBits: Int, val banks: Int)(implicit p: Parameters) extends XSBundle{
272  def tagBits = VAddrBits - idxBits - instOffsetBits
273
274  val tag = UInt(tagBits.W)
275  val idx = UInt(idxBits.W)
276  val offset = UInt(instOffsetBits.W)
277
278  def fromUInt(x: UInt) = x.asTypeOf(UInt(VAddrBits.W)).asTypeOf(this)
279  def getTag(x: UInt) = fromUInt(x).tag
280  def getIdx(x: UInt) = fromUInt(x).idx
281  def getBank(x: UInt) = if (banks > 1) getIdx(x)(log2Up(banks) - 1, 0) else 0.U
282  def getBankIdx(x: UInt) = if (banks > 1) getIdx(x)(idxBits - 1, log2Up(banks)) else getIdx(x)
283}
284
285@chiselName
286class BranchPrediction(implicit p: Parameters) extends XSBundle with HasBPUConst {
287  val br_taken_mask = Vec(numBr, Bool())
288
289  val slot_valids = Vec(totalSlot, Bool())
290
291  val targets = Vec(totalSlot, UInt(VAddrBits.W))
292
293  val is_jal = Bool()
294  val is_jalr = Bool()
295  val is_call = Bool()
296  val is_ret = Bool()
297  val is_br_sharing = Bool()
298
299  // val call_is_rvc = Bool()
300  val hit = Bool()
301
302  def br_slot_valids = slot_valids.init
303  def tail_slot_valid = slot_valids.last
304
305  def br_valids = {
306    VecInit(
307      if (shareTailSlot)
308        br_slot_valids :+ (tail_slot_valid && is_br_sharing)
309      else
310        br_slot_valids
311    )
312  }
313
314  def taken_mask_on_slot = {
315    VecInit(
316      if (shareTailSlot)
317        (br_slot_valids zip br_taken_mask.init).map{ case (t, v) => t && v } :+ (
318          (br_taken_mask.last && tail_slot_valid && is_br_sharing) ||
319          tail_slot_valid && !is_br_sharing
320        )
321      else
322        (br_slot_valids zip br_taken_mask).map{ case (v, t) => v && t } :+
323        tail_slot_valid
324    )
325  }
326
327  def taken = br_taken_mask.reduce(_||_) || slot_valids.last // || (is_jal || is_jalr)
328
329  def fromFtbEntry(entry: FTBEntry, pc: UInt) = {
330    slot_valids := entry.brSlots.map(_.valid) :+ entry.tailSlot.valid
331    targets := entry.getTargetVec(pc)
332    is_jal := entry.tailSlot.valid && entry.isJal
333    is_jalr := entry.tailSlot.valid && entry.isJalr
334    is_call := entry.tailSlot.valid && entry.isCall
335    is_ret := entry.tailSlot.valid && entry.isRet
336    is_br_sharing := entry.tailSlot.valid && entry.tailSlot.sharing
337  }
338  // override def toPrintable: Printable = {
339  //   p"-----------BranchPrediction----------- " +
340  //     p"[taken_mask] ${Binary(taken_mask.asUInt)} " +
341  //     p"[is_br] ${Binary(is_br.asUInt)}, [is_jal] ${Binary(is_jal.asUInt)} " +
342  //     p"[is_jalr] ${Binary(is_jalr.asUInt)}, [is_call] ${Binary(is_call.asUInt)}, [is_ret] ${Binary(is_ret.asUInt)} " +
343  //     p"[target] ${Hexadecimal(target)}}, [hit] $hit "
344  // }
345
346  def display(cond: Bool): Unit = {
347    XSDebug(cond, p"[taken_mask] ${Binary(br_taken_mask.asUInt)} [hit] $hit\n")
348  }
349}
350
351@chiselName
352class BranchPredictionBundle(implicit p: Parameters) extends XSBundle with HasBPUConst with BPUUtils{
353  val pc = UInt(VAddrBits.W)
354
355  val valid = Bool()
356
357  val hasRedirect = Bool()
358  val ftq_idx = new FtqPtr
359  // val hit = Bool()
360  val preds = new BranchPrediction
361
362  val folded_hist = new AllFoldedHistories(foldedGHistInfos)
363  val histPtr = new CGHPtr
364  val phist = UInt(PathHistoryLength.W)
365  val rasSp = UInt(log2Ceil(RasSize).W)
366  val rasTop = new RASEntry
367  val specCnt = Vec(numBr, UInt(10.W))
368  // val meta = UInt(MaxMetaLength.W)
369
370  val ftb_entry = new FTBEntry() // TODO: Send this entry to ftq
371
372  def real_slot_taken_mask(): Vec[Bool] = {
373    VecInit(preds.taken_mask_on_slot.map(_ && preds.hit))
374  }
375
376  // len numBr
377  def real_br_taken_mask(): Vec[Bool] = {
378    if (shareTailSlot)
379      VecInit(
380        preds.taken_mask_on_slot.map(_ && preds.hit).init :+
381        (preds.br_taken_mask.last && preds.tail_slot_valid && preds.is_br_sharing && preds.hit)
382      )
383    else
384      VecInit(real_slot_taken_mask().init)
385  }
386
387  // the vec indicating if ghr should shift on each branch
388  def shouldShiftVec =
389    VecInit(preds.br_valids.zipWithIndex.map{ case (v, i) =>
390      v && !real_br_taken_mask.take(i).reduceOption(_||_).getOrElse(false.B)})
391
392  def lastBrPosOH =
393    (!preds.hit || !preds.br_valids.reduce(_||_)) +: // not hit or no brs in entry
394    VecInit((0 until numBr).map(i =>
395      preds.br_valids(i) &&
396      !real_br_taken_mask.take(i).reduceOption(_||_).getOrElse(false.B) && // no brs taken in front it
397      (real_br_taken_mask()(i) || !preds.br_valids.drop(i+1).reduceOption(_||_).getOrElse(false.B)) && // no brs behind it
398      preds.hit
399    ))
400
401  def br_count(): UInt = {
402    val last_valid_idx = PriorityMux(
403      preds.br_valids.reverse :+ true.B,
404      (numBr to 0 by -1).map(_.U(log2Ceil(numBr+1).W))
405      )
406    val first_taken_idx = PriorityEncoder(false.B +: real_br_taken_mask)
407    Mux(last_valid_idx < first_taken_idx,
408      last_valid_idx,
409      first_taken_idx
410    )
411  }
412
413  def hit_taken_on_jmp =
414    !real_slot_taken_mask().init.reduce(_||_) &&
415    real_slot_taken_mask().last && !preds.is_br_sharing
416  def hit_taken_on_call = hit_taken_on_jmp && preds.is_call
417  def hit_taken_on_ret  = hit_taken_on_jmp && preds.is_ret
418  def hit_taken_on_jalr = hit_taken_on_jmp && preds.is_jalr
419
420  def fallThroughAddr = getFallThroughAddr(pc, ftb_entry.carry, ftb_entry.pftAddr)
421
422  def target(): UInt = {
423    val targetVec = preds.targets :+ fallThroughAddr :+ (pc + (FetchWidth*4).U)
424    val selVec = real_slot_taken_mask() :+ (preds.hit && !real_slot_taken_mask().asUInt.orR) :+ true.B
425    PriorityMux(selVec zip targetVec)
426  }
427  def genCfiIndex = {
428    val cfiIndex = Wire(ValidUndirectioned(UInt(log2Ceil(PredictWidth).W)))
429    cfiIndex.valid := real_slot_taken_mask().asUInt.orR
430    // when no takens, set cfiIndex to PredictWidth-1
431    cfiIndex.bits :=
432      ParallelPriorityMux(real_slot_taken_mask(), ftb_entry.getOffsetVec) |
433      Fill(log2Ceil(PredictWidth), (!real_slot_taken_mask().asUInt.orR).asUInt)
434    cfiIndex
435  }
436
437  def display(cond: Bool): Unit = {
438    XSDebug(cond, p"[pc] ${Hexadecimal(pc)}\n")
439    folded_hist.display(cond)
440    preds.display(cond)
441    ftb_entry.display(cond)
442  }
443}
444
445@chiselName
446class BranchPredictionResp(implicit p: Parameters) extends XSBundle with HasBPUConst {
447  // val valids = Vec(3, Bool())
448  val s1 = new BranchPredictionBundle()
449  val s2 = new BranchPredictionBundle()
450  val s3 = new BranchPredictionBundle()
451
452  def selectedResp =
453    PriorityMux(Seq(
454      ((s3.valid && s3.hasRedirect) -> s3),
455      ((s2.valid && s2.hasRedirect) -> s2),
456      (s1.valid -> s1)
457    ))
458  def selectedRespIdx =
459    PriorityMux(Seq(
460      ((s3.valid && s3.hasRedirect) -> BP_S3),
461      ((s2.valid && s2.hasRedirect) -> BP_S2),
462      (s1.valid -> BP_S1)
463    ))
464  def lastStage = s3
465}
466
467class BpuToFtqBundle(implicit p: Parameters) extends BranchPredictionResp with HasBPUConst {
468  val meta = UInt(MaxMetaLength.W)
469}
470
471object BpuToFtqBundle {
472  def apply(resp: BranchPredictionResp)(implicit p: Parameters): BpuToFtqBundle = {
473    val e = Wire(new BpuToFtqBundle())
474    e.s1 := resp.s1
475    e.s2 := resp.s2
476    e.s3 := resp.s3
477
478    e.meta := DontCare
479    e
480  }
481}
482
483class BranchPredictionUpdate(implicit p: Parameters) extends BranchPredictionBundle with HasBPUConst {
484  val mispred_mask = Vec(numBr+1, Bool())
485  val false_hit = Bool()
486  val new_br_insert_pos = Vec(numBr, Bool())
487  val old_entry = Bool()
488  val meta = UInt(MaxMetaLength.W)
489  val full_target = UInt(VAddrBits.W)
490
491  def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = {
492    folded_hist := entry.folded_hist
493    histPtr := entry.histPtr
494    phist := entry.phist
495    rasSp := entry.rasSp
496    rasTop := entry.rasEntry
497    specCnt := entry.specCnt
498    this
499  }
500
501  override def display(cond: Bool) = {
502    XSDebug(cond, p"-----------BranchPredictionUpdate-----------\n")
503    XSDebug(cond, p"[mispred_mask] ${Binary(mispred_mask.asUInt)} [false_hit] $false_hit\n")
504    XSDebug(cond, p"[new_br_insert_pos] ${Binary(new_br_insert_pos.asUInt)}\n")
505    super.display(cond)
506    XSDebug(cond, p"--------------------------------------------\n")
507  }
508}
509
510class BranchPredictionRedirect(implicit p: Parameters) extends Redirect with HasBPUConst {
511  // override def toPrintable: Printable = {
512  //   p"-----------BranchPredictionRedirect----------- " +
513  //     p"-----------cfiUpdate----------- " +
514  //     p"[pc] ${Hexadecimal(cfiUpdate.pc)} " +
515  //     p"[predTaken] ${cfiUpdate.predTaken}, [taken] ${cfiUpdate.taken}, [isMisPred] ${cfiUpdate.isMisPred} " +
516  //     p"[target] ${Hexadecimal(cfiUpdate.target)} " +
517  //     p"------------------------------- " +
518  //     p"[robPtr] f=${robIdx.flag} v=${robIdx.value} " +
519  //     p"[ftqPtr] f=${ftqIdx.flag} v=${ftqIdx.value} " +
520  //     p"[ftqOffset] ${ftqOffset} " +
521  //     p"[level] ${level}, [interrupt] ${interrupt} " +
522  //     p"[stFtqIdx] f=${stFtqIdx.flag} v=${stFtqIdx.value} " +
523  //     p"[stFtqOffset] ${stFtqOffset} " +
524  //     p"\n"
525
526  // }
527
528  def display(cond: Bool): Unit = {
529    XSDebug(cond, p"-----------BranchPredictionRedirect----------- \n")
530    XSDebug(cond, p"-----------cfiUpdate----------- \n")
531    XSDebug(cond, p"[pc] ${Hexadecimal(cfiUpdate.pc)}\n")
532    // XSDebug(cond, p"[hist] ${Binary(cfiUpdate.hist.predHist)}\n")
533    XSDebug(cond, p"[br_hit] ${cfiUpdate.br_hit} [isMisPred] ${cfiUpdate.isMisPred}\n")
534    XSDebug(cond, p"[pred_taken] ${cfiUpdate.predTaken} [taken] ${cfiUpdate.taken} [isMisPred] ${cfiUpdate.isMisPred}\n")
535    XSDebug(cond, p"[target] ${Hexadecimal(cfiUpdate.target)} \n")
536    XSDebug(cond, p"[shift] ${cfiUpdate.shift}\n")
537    XSDebug(cond, p"------------------------------- \n")
538    XSDebug(cond, p"[robPtr] f=${robIdx.flag} v=${robIdx.value}\n")
539    XSDebug(cond, p"[ftqPtr] f=${ftqIdx.flag} v=${ftqIdx.value} \n")
540    XSDebug(cond, p"[ftqOffset] ${ftqOffset} \n")
541    XSDebug(cond, p"[stFtqIdx] f=${stFtqIdx.flag} v=${stFtqIdx.value}\n")
542    XSDebug(cond, p"[stFtqOffset] ${stFtqOffset}\n")
543    XSDebug(cond, p"---------------------------------------------- \n")
544  }
545}
546