15db4956bSzhanglyGitpackage xiangshan.backend.issue 25db4956bSzhanglyGit 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 45db4956bSzhanglyGitimport chisel3._ 55db4956bSzhanglyGitimport chisel3.util._ 65db4956bSzhanglyGitimport utility.HasCircularQueuePtrHelper 75db4956bSzhanglyGitimport utils.{MathUtils, OptionWrapper} 85db4956bSzhanglyGitimport xiangshan._ 95db4956bSzhanglyGitimport xiangshan.backend.Bundles._ 105db4956bSzhanglyGitimport xiangshan.backend.fu.FuType 115db4956bSzhanglyGitimport xiangshan.backend.datapath.DataSource 125db4956bSzhanglyGitimport xiangshan.backend.rob.RobPtr 13*aa2bcc31SzhanglyGitimport xiangshan.backend.issue.EntryBundles._ 142d270511Ssinsanctionimport xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr} 155db4956bSzhanglyGit 165db4956bSzhanglyGit 175db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 185db4956bSzhanglyGit //input 19*aa2bcc31SzhanglyGit val commonIn = new CommonInBundle 20aa2b5219Ssinsanction val enqDelayWakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 21aa2b5219Ssinsanction val enqDelayWakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 22aa2b5219Ssinsanction val enqDelayOg0Cancel = Input(ExuOH(backendParams.numExu)) 237cbafe1aSzhanglyGit val enqDelayLdCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 245db4956bSzhanglyGit 25*aa2bcc31SzhanglyGit //output 26*aa2bcc31SzhanglyGit val commonOut = new CommonOutBundle 27*aa2bcc31SzhanglyGit val transEntry = ValidIO(new EntryBundle) 28*aa2bcc31SzhanglyGit 29*aa2bcc31SzhanglyGit def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 305db4956bSzhanglyGit} 315db4956bSzhanglyGit 325db4956bSzhanglyGitclass EnqEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 335db4956bSzhanglyGit val io = IO(new EnqEntryIO) 345db4956bSzhanglyGit 355db4956bSzhanglyGit val validReg = RegInit(false.B) 36aa2b5219Ssinsanction val enqDelayValidReg = RegInit(false.B) 37*aa2bcc31SzhanglyGit val entryReg = Reg(new EntryBundle) 385db4956bSzhanglyGit 39*aa2bcc31SzhanglyGit val common = Wire(new CommonWireBundle) 405db4956bSzhanglyGit val entryUpdate = Wire(new EntryBundle) 41*aa2bcc31SzhanglyGit val entryRegNext = Wire(new EntryBundle) 42aa2b5219Ssinsanction val enqDelayValidRegNext= Wire(Bool()) 43*aa2bcc31SzhanglyGit val hasWakeupIQ = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle)) 445db4956bSzhanglyGit 45aa2b5219Ssinsanction val currentStatus = Wire(new Status()) 46aa2b5219Ssinsanction val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState())) 47aa2b5219Ssinsanction val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource())) 48aa2b5219Ssinsanction val enqDelaySrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH()))) 49aa2b5219Ssinsanction val enqDelaySrcTimer = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W)))) 50aa2b5219Ssinsanction val enqDelaySrcLoadDependency = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))) 51aa2b5219Ssinsanction 52aa2b5219Ssinsanction val enqDelaySrcWakeUpByWB: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 53aa2b5219Ssinsanction val enqDelaySrcWakeUpByIQ: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 54aa2b5219Ssinsanction val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]] = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 55aa2b5219Ssinsanction val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]] = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 56aa2b5219Ssinsanction 575db4956bSzhanglyGit //Reg 58*aa2bcc31SzhanglyGit validReg := common.validRegNext 595db4956bSzhanglyGit entryReg := entryRegNext 60aa2b5219Ssinsanction enqDelayValidReg := enqDelayValidRegNext 615db4956bSzhanglyGit 625db4956bSzhanglyGit //Wire 63*aa2bcc31SzhanglyGit CommonWireConnect(common, hasWakeupIQ, validReg, entryReg, io.commonIn, true) 645db4956bSzhanglyGit 65*aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 66*aa2bcc31SzhanglyGit entryRegNext := io.commonIn.enq.bits 675db4956bSzhanglyGit }.otherwise { 685db4956bSzhanglyGit entryRegNext := entryUpdate 695db4956bSzhanglyGit } 705db4956bSzhanglyGit 71*aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 72aa2b5219Ssinsanction enqDelayValidRegNext := true.B 73aa2b5219Ssinsanction }.otherwise { 74aa2b5219Ssinsanction enqDelayValidRegNext := false.B 75aa2b5219Ssinsanction } 76aa2b5219Ssinsanction 775db4956bSzhanglyGit if (params.hasIQWakeUp) { 78*aa2bcc31SzhanglyGit ShiftLoadDependency(hasWakeupIQ.get) 79*aa2bcc31SzhanglyGit CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, entryReg.status, io.commonIn, true) 805db4956bSzhanglyGit } 815db4956bSzhanglyGit 82aa2b5219Ssinsanction // enq delay wakeup 83aa2b5219Ssinsanction enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) => 84*aa2bcc31SzhanglyGit wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.srcStatus(i).psrc, entryReg.status.srcStatus(i).srcType)), x.valid).head 85aa2b5219Ssinsanction ).reduce(_ || _) 86aa2b5219Ssinsanction } 87aa2b5219Ssinsanction 88aa2b5219Ssinsanction if (params.hasIQWakeUp) { 89aa2b5219Ssinsanction val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x => 90*aa2bcc31SzhanglyGit x.bits.wakeUpFromIQ(entryReg.status.srcStatus.map(_.psrc) zip entryReg.status.srcStatus.map(_.srcType)) 91aa2b5219Ssinsanction ).toIndexedSeq.transpose 92d20f567fSzhanglyGit val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat} 93aa2b5219Ssinsanction enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel })) 94aa2b5219Ssinsanction } else { 95aa2b5219Ssinsanction enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec) 96aa2b5219Ssinsanction } 97aa2b5219Ssinsanction 98aa2b5219Ssinsanction if (params.hasIQWakeUp) { 99aa2b5219Ssinsanction enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) => 100aa2b5219Ssinsanction val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq) 101aa2b5219Ssinsanction wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel 102aa2b5219Ssinsanction } 103aa2b5219Ssinsanction } else { 104aa2b5219Ssinsanction enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ) 105aa2b5219Ssinsanction } 106aa2b5219Ssinsanction 107aa2b5219Ssinsanction enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency)) 108aa2b5219Ssinsanction .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) => 109aa2b5219Ssinsanction dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) => 110aa2b5219Ssinsanction if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 111aa2b5219Ssinsanction dp := (ldp << 2).asUInt | 2.U 112aa2b5219Ssinsanction else 113aa2b5219Ssinsanction dp := ldp << 1 114aa2b5219Ssinsanction } 115aa2b5219Ssinsanction } 116aa2b5219Ssinsanction 117aa2b5219Ssinsanction for (i <- 0 until params.numRegSrc) { 118*aa2bcc31SzhanglyGit enqDelaySrcState(i) := entryReg.status.srcStatus(i).srcState | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i) 119aa2b5219Ssinsanction enqDelayDataSources(i).value := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, DataSource.reg) 120aa2b5219Ssinsanction if (params.hasIQWakeUp) { 121aa2b5219Ssinsanction val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR 122aa2b5219Ssinsanction val wakeUpOH = enqDelaySrcWakeUpByIQVec(i) 123acf41503Ssinsanction enqDelaySrcWakeUpL1ExuOH.get(i) := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq) 124aa2b5219Ssinsanction enqDelaySrcTimer.get(i) := Mux(wakeUpValid, 2.U, 3.U) 125*aa2bcc31SzhanglyGit enqDelaySrcLoadDependency.get(i) := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency.get) 126aa2b5219Ssinsanction } 127aa2b5219Ssinsanction } 128aa2b5219Ssinsanction currentStatus := entryReg.status 129aa2b5219Ssinsanction when (enqDelayValidReg) { 130*aa2bcc31SzhanglyGit currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) => 131*aa2bcc31SzhanglyGit srcStatus.srcState := enqDelaySrcState(srcIdx) 132*aa2bcc31SzhanglyGit srcStatus.dataSources := enqDelayDataSources(srcIdx) 133*aa2bcc31SzhanglyGit srcStatus.srcTimer.foreach(_ := enqDelaySrcTimer.get(srcIdx)) 134*aa2bcc31SzhanglyGit srcStatus.srcLoadDependency.foreach(_ := enqDelaySrcLoadDependency.get(srcIdx)) 135*aa2bcc31SzhanglyGit } 136aa2b5219Ssinsanction } 137aa2b5219Ssinsanction 138acf41503Ssinsanction if (params.hasIQWakeUp) { 139*aa2bcc31SzhanglyGit currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach { 140acf41503Ssinsanction case ((currExuOH, regExuOH), enqDelayExuOH) => 141acf41503Ssinsanction currExuOH := 0.U.asTypeOf(currExuOH) 142acf41503Ssinsanction params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x))) 143acf41503Ssinsanction } 144acf41503Ssinsanction } 145acf41503Ssinsanction 146*aa2bcc31SzhanglyGit EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true) 147e08589a5Ssinsanction 148*aa2bcc31SzhanglyGit CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryReg, currentStatus, io.commonIn, true) 149*aa2bcc31SzhanglyGit io.transEntry.valid := validReg && !common.flushed && !common.deqSuccess 1505db4956bSzhanglyGit io.transEntry.bits := entryUpdate 1515db4956bSzhanglyGit} 1525db4956bSzhanglyGit 1535db4956bSzhanglyGitclass EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 1545db4956bSzhanglyGit with HasCircularQueuePtrHelper { 155*aa2bcc31SzhanglyGit entryUpdate.status.blocked := EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, true) 1565db4956bSzhanglyGit val memStatusUpdate = entryUpdate.status.mem.get 157*aa2bcc31SzhanglyGit val memStatus = entryReg.status.mem.get 158*aa2bcc31SzhanglyGit val deqFailedForStdInvalid = io.commonIn.issueResp.valid && io.commonIn.issueResp.bits.respType === RSFeedbackType.dataInvalid 1595db4956bSzhanglyGit 1605db4956bSzhanglyGit when(deqFailedForStdInvalid) { 161*aa2bcc31SzhanglyGit memStatusUpdate.waitForSqIdx := io.commonIn.issueResp.bits.dataInvalidSqIdx 1625db4956bSzhanglyGit memStatusUpdate.waitForRobIdx := memStatus.waitForRobIdx 1635db4956bSzhanglyGit memStatusUpdate.waitForStd := true.B 1645db4956bSzhanglyGit memStatusUpdate.strictWait := memStatus.strictWait 1655db4956bSzhanglyGit memStatusUpdate.sqIdx := memStatus.sqIdx 1665db4956bSzhanglyGit }.otherwise { 1675db4956bSzhanglyGit memStatusUpdate := memStatus 1685db4956bSzhanglyGit } 1695db4956bSzhanglyGit 1705db4956bSzhanglyGit} 1715db4956bSzhanglyGit 1722d270511Ssinsanctionclass EnqEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntryMem { 1732d270511Ssinsanction 1742d270511Ssinsanction require(params.isVecMemAddrIQ, "EnqEntryVecMemAddr can only be instance of VecMemAddr IQ") 1752d270511Ssinsanction 1762d270511Ssinsanction val vecMemStatus = entryReg.status.vecMem.get 1772d270511Ssinsanction val vecMemStatusNext = entryRegNext.status.vecMem.get 1782d270511Ssinsanction val vecMemStatusUpdate = entryUpdate.status.vecMem.get 179*aa2bcc31SzhanglyGit val fromLsq = io.commonIn.fromLsq.get 1802d270511Ssinsanction 181*aa2bcc31SzhanglyGit when (io.commonIn.enq.valid && common.enqReady) { 182*aa2bcc31SzhanglyGit vecMemStatusNext.sqIdx := io.commonIn.enq.bits.status.vecMem.get.sqIdx 183*aa2bcc31SzhanglyGit vecMemStatusNext.lqIdx := io.commonIn.enq.bits.status.vecMem.get.lqIdx 1842d270511Ssinsanction }.otherwise { 1852d270511Ssinsanction vecMemStatusNext := vecMemStatusUpdate 1862d270511Ssinsanction } 1872d270511Ssinsanction vecMemStatusUpdate := vecMemStatus 1882d270511Ssinsanction 1892d270511Ssinsanction val isLsqHead = { 19029b863e5Szhanglinjuan // if (params.isVecLdAddrIQ) 19131c1fcd8Szhanglinjuan entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 19229b863e5Szhanglinjuan // else 19331c1fcd8Szhanglinjuan entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 1942d270511Ssinsanction } 1952d270511Ssinsanction 196*aa2bcc31SzhanglyGit entryUpdate.status.vecMem.get.uopIdx := entryReg.status.vecMem.get.uopIdx 1972d270511Ssinsanction} 1982d270511Ssinsanction 1992d270511Ssinsanctionclass EnqEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 2002d270511Ssinsanction with HasCircularQueuePtrHelper { 2012d270511Ssinsanction 2022d270511Ssinsanction require(params.isVecStDataIQ, "EnqEntryVecMemData can only be instance of VecMemData IQ") 2032d270511Ssinsanction 2042d270511Ssinsanction val vecMemStatus = entryReg.status.vecMem.get 2052d270511Ssinsanction val vecMemStatusNext = entryRegNext.status.vecMem.get 2062d270511Ssinsanction val vecMemStatusUpdate = entryUpdate.status.vecMem.get 207*aa2bcc31SzhanglyGit val fromLsq = io.commonIn.fromLsq.get 2082d270511Ssinsanction 209*aa2bcc31SzhanglyGit when (io.commonIn.enq.valid && common.enqReady) { 210*aa2bcc31SzhanglyGit vecMemStatusNext.sqIdx := io.commonIn.enq.bits.status.vecMem.get.sqIdx 211*aa2bcc31SzhanglyGit vecMemStatusNext.lqIdx := io.commonIn.enq.bits.status.vecMem.get.lqIdx 2122d270511Ssinsanction }.otherwise { 2132d270511Ssinsanction vecMemStatusNext := vecMemStatusUpdate 2142d270511Ssinsanction } 2152d270511Ssinsanction vecMemStatusUpdate := vecMemStatus 2162d270511Ssinsanction 2172d270511Ssinsanction val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 2182d270511Ssinsanction 2192d270511Ssinsanction entryRegNext.status.blocked := !isLsqHead 2202d270511Ssinsanction entryUpdate.status.blocked := !isLsqHead 221*aa2bcc31SzhanglyGit entryUpdate.status.vecMem.get.uopIdx := entryReg.status.vecMem.get.uopIdx 2222d270511Ssinsanction} 2232d270511Ssinsanction 2245db4956bSzhanglyGitobject EnqEntry { 2255db4956bSzhanglyGit def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 2265db4956bSzhanglyGit iqParams.schdType match { 2275db4956bSzhanglyGit case IntScheduler() => new EnqEntry() 2285db4956bSzhanglyGit case MemScheduler() => 22997b279b9SXuan Hu if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new EnqEntryMem() 2302d270511Ssinsanction else if (iqParams.isVecMemAddrIQ) new EnqEntryVecMemAddr() 2312d270511Ssinsanction else if (iqParams.isVecStDataIQ) new EnqEntryVecMemData() 2325db4956bSzhanglyGit else new EnqEntry() 2335db4956bSzhanglyGit case VfScheduler() => new EnqEntry() 2345db4956bSzhanglyGit case _ => null 2355db4956bSzhanglyGit } 2365db4956bSzhanglyGit } 2375db4956bSzhanglyGit}