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