xref: /XiangShan/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala (revision 725e8ddc29ec6e96d16ceac10ae685c894296556)
1package xiangshan.backend.trace
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{CircularQueuePtr, HasCircularQueuePtrHelper}
7import xiangshan.{HasXSParameter, XSCoreParamsKey}
8
9class TraceBuffer(implicit val p: Parameters) extends Module
10  with HasXSParameter
11  with HasCircularQueuePtrHelper {
12
13  val io = IO(new Bundle {
14    val in = new Bundle{
15      val fromEncoder = Input(new FromEncoder)
16      val fromRob     = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthCompressed))
17    }
18
19    val out = new Bundle { // output groups to pcMem
20      val blockCommit = Output(Bool())
21      val groups = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed)
22    }
23  })
24
25  // buffer: compress info from robCommit
26  val traceTrap    = Reg(new TraceTrap)
27  val traceEntries = Reg(Vec(CommitWidth, ValidIO(new TraceBlock(false, IretireWidthCompressed))))
28  traceTrap := io.in.fromRob.trap
29
30  val blockCommit = RegInit(false.B) // to rob
31
32  /**
33   * compress, update blocks
34   */
35  val inValidVec = VecInit(io.in.fromRob.blocks.map(_.valid))
36  val inTypeIsNotNoneVec = VecInit(io.in.fromRob.blocks.map(block => Itype.isNotNone(block.bits.tracePipe.itype)))
37  val needPcVec = Wire(Vec(CommitWidth, Bool()))
38  for(i <- 0 until CommitWidth) {
39    val rightHasValid = if(i == CommitWidth - 1) false.B  else (inValidVec.asUInt(CommitWidth-1, i+1).orR)
40    needPcVec(i) := inValidVec(i) & (inTypeIsNotNoneVec(i) || !rightHasValid) & !blockCommit
41  }
42
43  val blocksUpdate = WireInit(io.in.fromRob.blocks)
44  for(i <- 1 until CommitWidth){
45    when(!needPcVec(i-1)){
46      blocksUpdate(i).bits.tracePipe.iretire := blocksUpdate(i - 1).bits.tracePipe.iretire + io.in.fromRob.blocks(i).bits.tracePipe.iretire
47      blocksUpdate(i).bits.ftqOffset.get := blocksUpdate(i - 1).bits.ftqOffset.get
48      blocksUpdate(i).bits.ftqIdx.get := blocksUpdate(i - 1).bits.ftqIdx.get
49     }
50  }
51
52  /**
53   * enq to traceEntries
54   */
55  val countVec = VecInit((0 until CommitWidth).map(i => PopCount(needPcVec.asUInt(i, 0))))
56  val numNeedPc = countVec(CommitWidth-1)
57
58  val enqPtr = RegInit(TracePtr(false.B, 0.U))
59  val deqPtr = RegInit(TracePtr(false.B, 0.U))
60  val deqPtrPre = RegNext(deqPtr)
61  val enqPtrNext = WireInit(enqPtr)
62  val deqPtrNext = WireInit(deqPtr)
63  enqPtr := enqPtrNext
64  deqPtr := deqPtrNext
65  val canNotTraceAll = distanceBetween(enqPtrNext, deqPtrNext) > 0.U
66  blockCommit := io.in.fromEncoder.enable && (canNotTraceAll || io.in.fromEncoder.stall)
67
68  enqPtrNext := enqPtr + numNeedPc
69  deqPtrNext := Mux(deqPtr + TraceGroupNum.U > enqPtrNext, enqPtrNext, deqPtr + TraceGroupNum.U)
70
71  val traceIdxVec = VecInit(countVec.map(count => (enqPtr + count - 1.U).value))
72
73  for(i <- 0 until CommitWidth){
74    when(needPcVec(i)){
75      traceEntries(traceIdxVec(i)) := blocksUpdate(i)
76    }
77  }
78
79  /**
80   * deq from traceEntries
81   */
82  val blockOut = WireInit(0.U.asTypeOf(io.out.groups))
83  blockOut.trap := traceTrap
84  for(i <- 0 until TraceGroupNum) {
85    when(deqPtrPre + i.U < enqPtr) {
86      blockOut.blocks(i) := traceEntries((deqPtrPre + i.U).value)
87    } .otherwise {
88      blockOut.blocks(i).valid := false.B
89    }
90  }
91
92  if(backendParams.debugEn){
93    dontTouch(countVec)
94    dontTouch(numNeedPc)
95    dontTouch(traceIdxVec)
96  }
97
98  io.out.blockCommit := blockCommit
99  io.out.groups := blockOut
100
101}
102
103class TracePtr(entries: Int) extends CircularQueuePtr[TracePtr](
104  entries
105) with HasCircularQueuePtrHelper {
106
107  def this()(implicit p: Parameters) = this(p(XSCoreParamsKey).CommitWidth)
108
109}
110
111object TracePtr {
112  def apply(f: Bool, v: UInt)(implicit p: Parameters): TracePtr = {
113    val ptr = Wire(new TracePtr)
114    ptr.flag := f
115    ptr.value := v
116    ptr
117  }
118}