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