xref: /XiangShan/src/main/scala/xiangshan/backend/trace/TraceBuffer.scala (revision 3ad9f3ddaa34c90ff2d7ac0fa9de518b1081f399)
14907ec88Schengguanghuipackage xiangshan.backend.trace
24907ec88Schengguanghui
34907ec88Schengguanghuiimport chisel3._
44907ec88Schengguanghuiimport chisel3.util._
54907ec88Schengguanghuiimport org.chipsalliance.cde.config.Parameters
64907ec88Schengguanghuiimport utility.{CircularQueuePtr, HasCircularQueuePtrHelper}
74907ec88Schengguanghuiimport xiangshan.{HasXSParameter, XSCoreParamsKey}
84907ec88Schengguanghui
94907ec88Schengguanghuiclass TraceBuffer(implicit val p: Parameters) extends Module
104907ec88Schengguanghui  with HasXSParameter
114907ec88Schengguanghui  with HasCircularQueuePtrHelper {
124907ec88Schengguanghui
134907ec88Schengguanghui  val io = IO(new Bundle {
144907ec88Schengguanghui    val in = new Bundle{
154907ec88Schengguanghui      val fromEncoder = Input(new FromEncoder)
164907ec88Schengguanghui      val fromRob     = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthCompressed))
174907ec88Schengguanghui    }
184907ec88Schengguanghui    val out = new Bundle { // output groups to pcMem
194907ec88Schengguanghui      val blockCommit = Output(Bool())
204907ec88Schengguanghui      val groups = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed)
214907ec88Schengguanghui    }
224907ec88Schengguanghui  })
234907ec88Schengguanghui
244907ec88Schengguanghui  // buffer: compress info from robCommit
254907ec88Schengguanghui  val traceEntries = Reg(Vec(CommitWidth, ValidIO(new TraceBlock(false, IretireWidthCompressed))))
264907ec88Schengguanghui  val blockCommit = RegInit(false.B) // to rob
274907ec88Schengguanghui
284907ec88Schengguanghui  /**
294907ec88Schengguanghui   * compress, update blocks
304907ec88Schengguanghui   */
314907ec88Schengguanghui  val inValidVec = VecInit(io.in.fromRob.blocks.map(_.valid))
324907ec88Schengguanghui  val inTypeIsNotNoneVec = VecInit(io.in.fromRob.blocks.map(block => Itype.isNotNone(block.bits.tracePipe.itype)))
334907ec88Schengguanghui  val needPcVec = Wire(Vec(CommitWidth, Bool()))
344907ec88Schengguanghui  for(i <- 0 until CommitWidth) {
354907ec88Schengguanghui    val rightHasValid = if(i == CommitWidth - 1) false.B  else (inValidVec.asUInt(CommitWidth-1, i+1).orR)
364907ec88Schengguanghui    needPcVec(i) := inValidVec(i) & (inTypeIsNotNoneVec(i) || !rightHasValid) & !blockCommit
374907ec88Schengguanghui  }
384907ec88Schengguanghui
394907ec88Schengguanghui  val blocksUpdate = WireInit(io.in.fromRob.blocks)
404907ec88Schengguanghui  for(i <- 1 until CommitWidth){
414907ec88Schengguanghui    when(!needPcVec(i-1)){
424907ec88Schengguanghui      blocksUpdate(i).bits.tracePipe.iretire := blocksUpdate(i - 1).bits.tracePipe.iretire + io.in.fromRob.blocks(i).bits.tracePipe.iretire
434907ec88Schengguanghui      blocksUpdate(i).bits.ftqOffset.get := blocksUpdate(i - 1).bits.ftqOffset.get
444907ec88Schengguanghui      blocksUpdate(i).bits.ftqIdx.get := blocksUpdate(i - 1).bits.ftqIdx.get
454907ec88Schengguanghui     }
464907ec88Schengguanghui  }
474907ec88Schengguanghui
484907ec88Schengguanghui  /**
494907ec88Schengguanghui   * enq to traceEntries
504907ec88Schengguanghui   */
514907ec88Schengguanghui  val countVec = VecInit((0 until CommitWidth).map(i => PopCount(needPcVec.asUInt(i, 0))))
524907ec88Schengguanghui  val numNeedPc = countVec(CommitWidth-1)
534907ec88Schengguanghui
544907ec88Schengguanghui  val enqPtr = RegInit(TracePtr(false.B, 0.U))
554907ec88Schengguanghui  val deqPtr = RegInit(TracePtr(false.B, 0.U))
564907ec88Schengguanghui  val deqPtrPre = RegNext(deqPtr)
574907ec88Schengguanghui  val enqPtrNext = WireInit(enqPtr)
584907ec88Schengguanghui  val deqPtrNext = WireInit(deqPtr)
594907ec88Schengguanghui  enqPtr := enqPtrNext
604907ec88Schengguanghui  deqPtr := deqPtrNext
614907ec88Schengguanghui  val canNotTraceAll = distanceBetween(enqPtrNext, deqPtrNext) > 0.U
624907ec88Schengguanghui  blockCommit := io.in.fromEncoder.enable && (canNotTraceAll || io.in.fromEncoder.stall)
634907ec88Schengguanghui
644907ec88Schengguanghui  enqPtrNext := enqPtr + numNeedPc
654907ec88Schengguanghui  deqPtrNext := Mux(deqPtr + TraceGroupNum.U > enqPtrNext, enqPtrNext, deqPtr + TraceGroupNum.U)
664907ec88Schengguanghui
674907ec88Schengguanghui  val traceIdxVec = VecInit(countVec.map(count => (enqPtr + count - 1.U).value))
684907ec88Schengguanghui  for(i <- 0 until CommitWidth){
694907ec88Schengguanghui    when(needPcVec(i)){
704907ec88Schengguanghui      traceEntries(traceIdxVec(i)) := blocksUpdate(i)
714907ec88Schengguanghui    }
724907ec88Schengguanghui  }
734907ec88Schengguanghui
744907ec88Schengguanghui  /**
754907ec88Schengguanghui   * deq from traceEntries
764907ec88Schengguanghui   */
774907ec88Schengguanghui  val blockOut = WireInit(0.U.asTypeOf(io.out.groups))
784907ec88Schengguanghui  for(i <- 0 until TraceGroupNum) {
794907ec88Schengguanghui    when(deqPtrPre + i.U < enqPtr) {
804907ec88Schengguanghui      blockOut.blocks(i) := traceEntries((deqPtrPre + i.U).value)
814907ec88Schengguanghui    } .otherwise {
824907ec88Schengguanghui      blockOut.blocks(i).valid := false.B
834907ec88Schengguanghui    }
844907ec88Schengguanghui  }
854907ec88Schengguanghui
86*c308d936Schengguanghui  io.out.blockCommit := blockCommit
87*c308d936Schengguanghui  io.out.groups := blockOut
88*c308d936Schengguanghui
894907ec88Schengguanghui  if(backendParams.debugEn){
904907ec88Schengguanghui    dontTouch(countVec)
914907ec88Schengguanghui    dontTouch(numNeedPc)
924907ec88Schengguanghui    dontTouch(traceIdxVec)
934907ec88Schengguanghui  }
944907ec88Schengguanghui}
954907ec88Schengguanghui
964907ec88Schengguanghuiclass TracePtr(entries: Int) extends CircularQueuePtr[TracePtr](
974907ec88Schengguanghui  entries
984907ec88Schengguanghui) with HasCircularQueuePtrHelper {
994907ec88Schengguanghui
1004907ec88Schengguanghui  def this()(implicit p: Parameters) = this(p(XSCoreParamsKey).CommitWidth)
1014907ec88Schengguanghui
1024907ec88Schengguanghui}
1034907ec88Schengguanghui
1044907ec88Schengguanghuiobject TracePtr {
1054907ec88Schengguanghui  def apply(f: Bool, v: UInt)(implicit p: Parameters): TracePtr = {
1064907ec88Schengguanghui    val ptr = Wire(new TracePtr)
1074907ec88Schengguanghui    ptr.flag := f
1084907ec88Schengguanghui    ptr.value := v
1094907ec88Schengguanghui    ptr
1104907ec88Schengguanghui  }
1114907ec88Schengguanghui}
112