1*5db4956bSzhanglyGitpackage xiangshan.backend.issue 2*5db4956bSzhanglyGit 3*5db4956bSzhanglyGitimport chipsalliance.rocketchip.config.Parameters 4*5db4956bSzhanglyGitimport chisel3._ 5*5db4956bSzhanglyGitimport chisel3.util._ 6*5db4956bSzhanglyGitimport utility.HasCircularQueuePtrHelper 7*5db4956bSzhanglyGitimport utils.{MathUtils, OptionWrapper} 8*5db4956bSzhanglyGitimport xiangshan._ 9*5db4956bSzhanglyGitimport xiangshan.backend.Bundles._ 10*5db4956bSzhanglyGitimport xiangshan.backend.fu.FuType 11*5db4956bSzhanglyGitimport xiangshan.backend.datapath.DataSource 12*5db4956bSzhanglyGitimport xiangshan.backend.rob.RobPtr 13*5db4956bSzhanglyGitimport xiangshan.mem.{MemWaitUpdateReq, SqPtr} 14*5db4956bSzhanglyGit 15*5db4956bSzhanglyGit 16*5db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 17*5db4956bSzhanglyGit //input 18*5db4956bSzhanglyGit val enq = Flipped(ValidIO(new EntryBundle)) 19*5db4956bSzhanglyGit val flush = Flipped(ValidIO(new Redirect)) 20*5db4956bSzhanglyGit val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 21*5db4956bSzhanglyGit val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 22*5db4956bSzhanglyGit val og0Cancel = Input(ExuVec(backendParams.numExu)) 23*5db4956bSzhanglyGit val og1Cancel = Input(ExuVec(backendParams.numExu)) 24*5db4956bSzhanglyGit val deqSel = Input(Bool()) 25*5db4956bSzhanglyGit val deqPortIdxWrite = Input(UInt(1.W)) 26*5db4956bSzhanglyGit val transSel = Input(Bool()) 27*5db4956bSzhanglyGit val issueResp = Flipped(ValidIO(new EntryDeqRespBundle)) 28*5db4956bSzhanglyGit //output 29*5db4956bSzhanglyGit val valid = Output(Bool()) 30*5db4956bSzhanglyGit val canIssue = Output(Bool()) 31*5db4956bSzhanglyGit val clear = Output(Bool()) 32*5db4956bSzhanglyGit val fuType = Output(FuType()) 33*5db4956bSzhanglyGit val dataSource = Output(Vec(params.numRegSrc, DataSource())) 34*5db4956bSzhanglyGit val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, ExuVec()))) 35*5db4956bSzhanglyGit val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, UInt(3.W)))) 36*5db4956bSzhanglyGit val transEntry = ValidIO(new EntryBundle) 37*5db4956bSzhanglyGit val isFirstIssue = Output(Bool()) 38*5db4956bSzhanglyGit val entry = ValidIO(new EntryBundle) 39*5db4956bSzhanglyGit val robIdx = Output(new RobPtr) 40*5db4956bSzhanglyGit val deqPortIdxRead = Output(UInt(1.W)) 41*5db4956bSzhanglyGit val issueTimerRead = Output(UInt(2.W)) 42*5db4956bSzhanglyGit // mem only 43*5db4956bSzhanglyGit val fromMem = if(params.isMemAddrIQ) Some(new Bundle { 44*5db4956bSzhanglyGit val stIssuePtr = Input(new SqPtr) 45*5db4956bSzhanglyGit val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 46*5db4956bSzhanglyGit }) else None 47*5db4956bSzhanglyGit 48*5db4956bSzhanglyGit def wakeup = wakeUpFromWB ++ wakeUpFromIQ 49*5db4956bSzhanglyGit} 50*5db4956bSzhanglyGit 51*5db4956bSzhanglyGitclass EnqEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 52*5db4956bSzhanglyGit val io = IO(new EnqEntryIO) 53*5db4956bSzhanglyGit 54*5db4956bSzhanglyGit val validReg = RegInit(false.B) 55*5db4956bSzhanglyGit val entryReg = Reg(new EntryBundle) 56*5db4956bSzhanglyGit 57*5db4956bSzhanglyGit val validRegNext = Wire(Bool()) 58*5db4956bSzhanglyGit val entryRegNext = Wire(new EntryBundle) 59*5db4956bSzhanglyGit val entryUpdate = Wire(new EntryBundle) 60*5db4956bSzhanglyGit val enqReady = Wire(Bool()) 61*5db4956bSzhanglyGit val clear = Wire(Bool()) 62*5db4956bSzhanglyGit val flushed = Wire(Bool()) 63*5db4956bSzhanglyGit val deqSuccess = Wire(Bool()) 64*5db4956bSzhanglyGit val srcWakeUp = Wire(Vec(params.numRegSrc, Bool())) 65*5db4956bSzhanglyGit val srcCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 66*5db4956bSzhanglyGit val srcWakeUpByIQVec = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 67*5db4956bSzhanglyGit 68*5db4956bSzhanglyGit //Reg 69*5db4956bSzhanglyGit validReg := validRegNext 70*5db4956bSzhanglyGit entryReg := entryRegNext 71*5db4956bSzhanglyGit 72*5db4956bSzhanglyGit //Wire 73*5db4956bSzhanglyGit when(io.enq.valid && enqReady) { 74*5db4956bSzhanglyGit validRegNext := true.B 75*5db4956bSzhanglyGit }.elsewhen(clear) { 76*5db4956bSzhanglyGit validRegNext := false.B 77*5db4956bSzhanglyGit }.otherwise { 78*5db4956bSzhanglyGit validRegNext := validReg 79*5db4956bSzhanglyGit } 80*5db4956bSzhanglyGit 81*5db4956bSzhanglyGit when(io.enq.valid && enqReady) { 82*5db4956bSzhanglyGit entryRegNext := io.enq.bits 83*5db4956bSzhanglyGit }.otherwise { 84*5db4956bSzhanglyGit entryRegNext := entryUpdate 85*5db4956bSzhanglyGit } 86*5db4956bSzhanglyGit 87*5db4956bSzhanglyGit enqReady := !validReg || clear 88*5db4956bSzhanglyGit clear := flushed || io.transSel || deqSuccess 89*5db4956bSzhanglyGit flushed := entryReg.status.robIdx.needFlush(io.flush) 90*5db4956bSzhanglyGit deqSuccess := io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.fuIdle 91*5db4956bSzhanglyGit srcWakeUp := io.wakeup.map(bundle => bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid)).transpose.map(VecInit(_).asUInt.orR) 92*5db4956bSzhanglyGit 93*5db4956bSzhanglyGit if (params.hasIQWakeUp) { 94*5db4956bSzhanglyGit srcCancelVec.get.zipWithIndex.foreach { case (srcCancel, srcIdx) => 95*5db4956bSzhanglyGit // level1 cancel: A(s)->C, A(s) are the level1 cancel 96*5db4956bSzhanglyGit val l1Cancel = (io.og0Cancel.asUInt & entryReg.status.srcWakeUpL1ExuOH.get(srcIdx).asUInt).orR && 97*5db4956bSzhanglyGit entryReg.status.srcTimer.get(srcIdx) === 1.U 98*5db4956bSzhanglyGit srcCancel := l1Cancel 99*5db4956bSzhanglyGit } 100*5db4956bSzhanglyGit } 101*5db4956bSzhanglyGit 102*5db4956bSzhanglyGit if (io.wakeUpFromIQ.isEmpty) { 103*5db4956bSzhanglyGit srcWakeUpByIQVec := 0.U.asTypeOf(srcWakeUpByIQVec) 104*5db4956bSzhanglyGit } else { 105*5db4956bSzhanglyGit val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.wakeUpFromIQ.map((bundle: ValidIO[IssueQueueIQWakeUpBundle]) => 106*5db4956bSzhanglyGit bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid) 107*5db4956bSzhanglyGit ).transpose 108*5db4956bSzhanglyGit srcWakeUpByIQVec := wakeupVec.map(x => VecInit(x)) 109*5db4956bSzhanglyGit } 110*5db4956bSzhanglyGit 111*5db4956bSzhanglyGit //entryUpdate 112*5db4956bSzhanglyGit entryUpdate.status.srcState.zip(entryReg.status.srcState).zip(srcWakeUp).zipWithIndex.foreach { case (((stateNext, state), wakeup), srcIdx) => 113*5db4956bSzhanglyGit val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 114*5db4956bSzhanglyGit stateNext := Mux(cancel, false.B, wakeup | state) 115*5db4956bSzhanglyGit } 116*5db4956bSzhanglyGit entryUpdate.status.dataSources.zip(entryReg.status.dataSources).zip(srcWakeUpByIQVec).foreach { 117*5db4956bSzhanglyGit case ((dataSourceNext: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]) => 118*5db4956bSzhanglyGit when(wakeUpByIQOH.asUInt.orR) { 119*5db4956bSzhanglyGit dataSourceNext.value := DataSource.forward 120*5db4956bSzhanglyGit }.elsewhen(dataSource.value === DataSource.forward) { 121*5db4956bSzhanglyGit dataSourceNext.value := DataSource.bypass 122*5db4956bSzhanglyGit }.otherwise { 123*5db4956bSzhanglyGit dataSourceNext.value := DataSource.reg 124*5db4956bSzhanglyGit } 125*5db4956bSzhanglyGit } 126*5db4956bSzhanglyGit if (params.hasIQWakeUp) { 127*5db4956bSzhanglyGit entryUpdate.status.srcWakeUpL1ExuOH.get.zip(srcWakeUpByIQVec).zipWithIndex.foreach { 128*5db4956bSzhanglyGit case ((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), srcIdx) => 129*5db4956bSzhanglyGit when(wakeUpByIQOH.asUInt.orR) { 130*5db4956bSzhanglyGit exuOH := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.map(x => MathUtils.IntToOH(x.bits.exuIdx).U(backendParams.numExu.W))).asBools 131*5db4956bSzhanglyGit }.otherwise { 132*5db4956bSzhanglyGit exuOH := entryReg.status.srcWakeUpL1ExuOH.get(srcIdx) 133*5db4956bSzhanglyGit } 134*5db4956bSzhanglyGit } 135*5db4956bSzhanglyGit entryUpdate.status.srcTimer.get.zip(entryReg.status.srcTimer.get).zip(srcWakeUpByIQVec).zipWithIndex.foreach { 136*5db4956bSzhanglyGit case (((srcIssuedTimerNext, srcIssuedTimer), wakeUpByIQOH: Vec[Bool]), srcIdx) => 137*5db4956bSzhanglyGit srcIssuedTimerNext := MuxCase(0.U, Seq( 138*5db4956bSzhanglyGit // T0: waked up by IQ, T1: reset timer as 1 139*5db4956bSzhanglyGit wakeUpByIQOH.asUInt.orR -> 1.U, 140*5db4956bSzhanglyGit // do not overflow 141*5db4956bSzhanglyGit srcIssuedTimer.andR -> srcIssuedTimer, 142*5db4956bSzhanglyGit // T2+: increase if this entry has still been valid, and this src has still been ready 143*5db4956bSzhanglyGit (validReg && SrcState.isReady(entryReg.status.srcState(srcIdx)) && entryReg.status.srcWakeUpL1ExuOH.get.asUInt.orR) -> (srcIssuedTimer + 1.U) 144*5db4956bSzhanglyGit )) 145*5db4956bSzhanglyGit } 146*5db4956bSzhanglyGit } 147*5db4956bSzhanglyGit entryUpdate.status.issueTimer := "b11".U //otherwise 148*5db4956bSzhanglyGit entryUpdate.status.deqPortIdx := 0.U //otherwise 149*5db4956bSzhanglyGit when(io.deqSel) { 150*5db4956bSzhanglyGit entryUpdate.status.issueTimer := 1.U 151*5db4956bSzhanglyGit entryUpdate.status.deqPortIdx := io.deqPortIdxWrite 152*5db4956bSzhanglyGit }.elsewhen(entryReg.status.issued){ 153*5db4956bSzhanglyGit entryUpdate.status.issueTimer := entryReg.status.issueTimer + 1.U 154*5db4956bSzhanglyGit entryUpdate.status.deqPortIdx := entryReg.status.deqPortIdx 155*5db4956bSzhanglyGit } 156*5db4956bSzhanglyGit entryUpdate.status.psrc := entryReg.status.psrc 157*5db4956bSzhanglyGit entryUpdate.status.srcType := entryReg.status.srcType 158*5db4956bSzhanglyGit entryUpdate.status.fuType := entryReg.status.fuType 159*5db4956bSzhanglyGit entryUpdate.status.robIdx := entryReg.status.robIdx 160*5db4956bSzhanglyGit entryUpdate.status.issued := entryReg.status.issued // otherwise 161*5db4956bSzhanglyGit when(!entryReg.status.srcReady){ 162*5db4956bSzhanglyGit entryUpdate.status.issued := false.B 163*5db4956bSzhanglyGit }.elsewhen(io.issueResp.valid) { 164*5db4956bSzhanglyGit when(RSFeedbackType.isStageSuccess(io.issueResp.bits.respType)) { 165*5db4956bSzhanglyGit entryUpdate.status.issued := true.B 166*5db4956bSzhanglyGit }.elsewhen(RSFeedbackType.isBlocked(io.issueResp.bits.respType)) { 167*5db4956bSzhanglyGit entryUpdate.status.issued := false.B 168*5db4956bSzhanglyGit } 169*5db4956bSzhanglyGit } 170*5db4956bSzhanglyGit entryUpdate.status.firstIssue := io.deqSel || entryReg.status.firstIssue 171*5db4956bSzhanglyGit entryUpdate.status.blocked := false.B //todo 172*5db4956bSzhanglyGit //remain imm and payload 173*5db4956bSzhanglyGit entryUpdate.imm := entryReg.imm 174*5db4956bSzhanglyGit entryUpdate.payload := entryReg.payload 175*5db4956bSzhanglyGit if(params.needPc) { 176*5db4956bSzhanglyGit entryUpdate.status.pc.get := entryReg.status.pc.get 177*5db4956bSzhanglyGit entryUpdate.status.target.get := entryReg.status.target.get 178*5db4956bSzhanglyGit } 179*5db4956bSzhanglyGit 180*5db4956bSzhanglyGit //output 181*5db4956bSzhanglyGit io.transEntry.valid := validReg && io.transSel && !flushed && !deqSuccess 182*5db4956bSzhanglyGit io.transEntry.bits := entryUpdate 183*5db4956bSzhanglyGit io.canIssue := entryReg.status.canIssue && validReg 184*5db4956bSzhanglyGit io.clear := clear 185*5db4956bSzhanglyGit io.fuType := entryReg.status.fuType 186*5db4956bSzhanglyGit io.dataSource := entryReg.status.dataSources 187*5db4956bSzhanglyGit io.srcWakeUpL1ExuOH.foreach(_ := entryReg.status.srcWakeUpL1ExuOH.get) 188*5db4956bSzhanglyGit io.srcTimer.foreach(_ := entryReg.status.srcTimer.get) 189*5db4956bSzhanglyGit io.valid := validReg 190*5db4956bSzhanglyGit io.isFirstIssue := !entryReg.status.firstIssue 191*5db4956bSzhanglyGit io.entry.valid := validReg 192*5db4956bSzhanglyGit io.entry.bits := entryReg 193*5db4956bSzhanglyGit io.robIdx := entryReg.status.robIdx 194*5db4956bSzhanglyGit io.issueTimerRead := Mux(io.deqSel, 0.U, entryReg.status.issueTimer) 195*5db4956bSzhanglyGit io.deqPortIdxRead := Mux(io.deqSel, io.deqPortIdxWrite, entryReg.status.deqPortIdx) 196*5db4956bSzhanglyGit} 197*5db4956bSzhanglyGit 198*5db4956bSzhanglyGitclass EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 199*5db4956bSzhanglyGit with HasCircularQueuePtrHelper { 200*5db4956bSzhanglyGit val fromMem = io.fromMem.get 201*5db4956bSzhanglyGit 202*5db4956bSzhanglyGit val memStatus = entryReg.status.mem.get 203*5db4956bSzhanglyGit println("memStatus" + memStatus) 204*5db4956bSzhanglyGit val memStatusNext = entryRegNext.status.mem.get 205*5db4956bSzhanglyGit val memStatusUpdate = entryUpdate.status.mem.get 206*5db4956bSzhanglyGit 207*5db4956bSzhanglyGit // load cannot be issued before older store, unless meet some condition 208*5db4956bSzhanglyGit val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 209*5db4956bSzhanglyGit 210*5db4956bSzhanglyGit val deqFailedForStdInvalid = io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.dataInvalid 211*5db4956bSzhanglyGit 212*5db4956bSzhanglyGit val staWaitedReleased = Cat( 213*5db4956bSzhanglyGit fromMem.memWaitUpdateReq.staIssue.map(x => x.valid && x.bits.uop.robIdx.value === memStatusNext.waitForRobIdx.value) 214*5db4956bSzhanglyGit ).orR 215*5db4956bSzhanglyGit val stdWaitedReleased = Cat( 216*5db4956bSzhanglyGit fromMem.memWaitUpdateReq.stdIssue.map(x => x.valid && x.bits.uop.sqIdx.value === memStatusNext.waitForSqIdx.value) 217*5db4956bSzhanglyGit ).orR 218*5db4956bSzhanglyGit val olderStaNotViolate = staWaitedReleased && !memStatusNext.strictWait 219*5db4956bSzhanglyGit val olderStdReady = stdWaitedReleased && memStatusNext.waitForStd 220*5db4956bSzhanglyGit val waitStd = !olderStdReady 221*5db4956bSzhanglyGit val waitSta = !olderStaNotViolate 222*5db4956bSzhanglyGit 223*5db4956bSzhanglyGit when (io.enq.valid && enqReady) { 224*5db4956bSzhanglyGit memStatusNext.waitForSqIdx := io.enq.bits.status.mem.get.waitForSqIdx 225*5db4956bSzhanglyGit // update by lfst at dispatch stage 226*5db4956bSzhanglyGit memStatusNext.waitForRobIdx := io.enq.bits.status.mem.get.waitForRobIdx 227*5db4956bSzhanglyGit // new load inst don't known if it is blocked by store data ahead of it 228*5db4956bSzhanglyGit memStatusNext.waitForStd := false.B 229*5db4956bSzhanglyGit // update by ssit at rename stage 230*5db4956bSzhanglyGit memStatusNext.strictWait := io.enq.bits.status.mem.get.strictWait 231*5db4956bSzhanglyGit memStatusNext.sqIdx := io.enq.bits.status.mem.get.sqIdx 232*5db4956bSzhanglyGit }.otherwise { 233*5db4956bSzhanglyGit memStatusNext := memStatusUpdate 234*5db4956bSzhanglyGit } 235*5db4956bSzhanglyGit 236*5db4956bSzhanglyGit when(deqFailedForStdInvalid) { 237*5db4956bSzhanglyGit memStatusUpdate.waitForSqIdx := io.issueResp.bits.dataInvalidSqIdx 238*5db4956bSzhanglyGit memStatusUpdate.waitForRobIdx := memStatus.waitForRobIdx 239*5db4956bSzhanglyGit memStatusUpdate.waitForStd := true.B 240*5db4956bSzhanglyGit memStatusUpdate.strictWait := memStatus.strictWait 241*5db4956bSzhanglyGit memStatusUpdate.sqIdx := memStatus.sqIdx 242*5db4956bSzhanglyGit }.otherwise { 243*5db4956bSzhanglyGit memStatusUpdate := memStatus 244*5db4956bSzhanglyGit } 245*5db4956bSzhanglyGit 246*5db4956bSzhanglyGit val shouldBlock = Mux(io.enq.valid && enqReady, io.enq.bits.status.blocked, entryReg.status.blocked) 247*5db4956bSzhanglyGit val blockNotReleased = waitStd || waitSta 248*5db4956bSzhanglyGit val respBlock = deqFailedForStdInvalid 249*5db4956bSzhanglyGit entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 250*5db4956bSzhanglyGit entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 251*5db4956bSzhanglyGit 252*5db4956bSzhanglyGit} 253*5db4956bSzhanglyGit 254*5db4956bSzhanglyGitobject EnqEntry { 255*5db4956bSzhanglyGit def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 256*5db4956bSzhanglyGit iqParams.schdType match { 257*5db4956bSzhanglyGit case IntScheduler() => new EnqEntry() 258*5db4956bSzhanglyGit case MemScheduler() => 259*5db4956bSzhanglyGit if (iqParams.StdCnt == 0) new EnqEntryMem() 260*5db4956bSzhanglyGit else new EnqEntry() 261*5db4956bSzhanglyGit case VfScheduler() => new EnqEntry() 262*5db4956bSzhanglyGit case _ => null 263*5db4956bSzhanglyGit } 264*5db4956bSzhanglyGit } 265*5db4956bSzhanglyGit}