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}