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 13aa2bcc31SzhanglyGitimport xiangshan.backend.issue.EntryBundles._ 142d270511Ssinsanctionimport xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr} 155db4956bSzhanglyGit 165db4956bSzhanglyGit 175db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 185db4956bSzhanglyGit //input 19aa2bcc31SzhanglyGit 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 25aa2bcc31SzhanglyGit //output 26aa2bcc31SzhanglyGit val commonOut = new CommonOutBundle 27aa2bcc31SzhanglyGit 28aa2bcc31SzhanglyGit def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 295db4956bSzhanglyGit} 305db4956bSzhanglyGit 31df26db8aSsinsanctionclass EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 325db4956bSzhanglyGit val io = IO(new EnqEntryIO) 335db4956bSzhanglyGit 345db4956bSzhanglyGit val validReg = RegInit(false.B) 35aa2b5219Ssinsanction val enqDelayValidReg = RegInit(false.B) 365db4956bSzhanglyGit 37aa2bcc31SzhanglyGit val common = Wire(new CommonWireBundle) 385db4956bSzhanglyGit val entryUpdate = Wire(new EntryBundle) 39aa2bcc31SzhanglyGit val entryRegNext = Wire(new EntryBundle) 40aa2b5219Ssinsanction val enqDelayValidRegNext= Wire(Bool()) 41aa2bcc31SzhanglyGit val hasWakeupIQ = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle)) 425db4956bSzhanglyGit 43aa2b5219Ssinsanction val currentStatus = Wire(new Status()) 44aa2b5219Ssinsanction val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState())) 45aa2b5219Ssinsanction val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource())) 46aa2b5219Ssinsanction val enqDelaySrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH()))) 47aa2b5219Ssinsanction val enqDelaySrcTimer = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W)))) 48eea4a3caSzhanglyGit val enqDelaySrcLoadDependency = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))) 49aa2b5219Ssinsanction 50aa2b5219Ssinsanction val enqDelaySrcWakeUpByWB: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 51aa2b5219Ssinsanction val enqDelaySrcWakeUpByIQ: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 52aa2b5219Ssinsanction val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]] = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 53aa2b5219Ssinsanction val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]] = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 54aa2b5219Ssinsanction 555db4956bSzhanglyGit //Reg 56*41dbbdfdSsinceforYy val entryReg = RegEnable(entryRegNext, validReg || common.validRegNext) 57aa2bcc31SzhanglyGit validReg := common.validRegNext 58aa2b5219Ssinsanction enqDelayValidReg := enqDelayValidRegNext 595db4956bSzhanglyGit 605db4956bSzhanglyGit //Wire 610dfdb52aSzhanglyGit CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true) 625db4956bSzhanglyGit 6328607074Ssinsanction when(io.commonIn.enq.valid) { 6428607074Ssinsanction assert(common.enqReady, "Entry is not ready when enq is valid\n") 6528607074Ssinsanction } 6628607074Ssinsanction 67aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 68aa2bcc31SzhanglyGit entryRegNext := io.commonIn.enq.bits 695db4956bSzhanglyGit }.otherwise { 705db4956bSzhanglyGit entryRegNext := entryUpdate 715db4956bSzhanglyGit } 725db4956bSzhanglyGit 73aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 74aa2b5219Ssinsanction enqDelayValidRegNext := true.B 75aa2b5219Ssinsanction }.otherwise { 76aa2b5219Ssinsanction enqDelayValidRegNext := false.B 77aa2b5219Ssinsanction } 78aa2b5219Ssinsanction 795db4956bSzhanglyGit if (params.hasIQWakeUp) { 80aa2bcc31SzhanglyGit ShiftLoadDependency(hasWakeupIQ.get) 810dfdb52aSzhanglyGit CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true) 825db4956bSzhanglyGit } 835db4956bSzhanglyGit 84aa2b5219Ssinsanction // enq delay wakeup 85aa2b5219Ssinsanction enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) => 86aa2bcc31SzhanglyGit wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.srcStatus(i).psrc, entryReg.status.srcStatus(i).srcType)), x.valid).head 87aa2b5219Ssinsanction ).reduce(_ || _) 88aa2b5219Ssinsanction } 89aa2b5219Ssinsanction 90aa2b5219Ssinsanction if (params.hasIQWakeUp) { 91aa2b5219Ssinsanction val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x => 92aa2bcc31SzhanglyGit x.bits.wakeUpFromIQ(entryReg.status.srcStatus.map(_.psrc) zip entryReg.status.srcStatus.map(_.srcType)) 93aa2b5219Ssinsanction ).toIndexedSeq.transpose 94d20f567fSzhanglyGit val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat} 95aa2b5219Ssinsanction enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel })) 96aa2b5219Ssinsanction } else { 97aa2b5219Ssinsanction enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec) 98aa2b5219Ssinsanction } 99aa2b5219Ssinsanction 100aa2b5219Ssinsanction if (params.hasIQWakeUp) { 101aa2b5219Ssinsanction enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) => 102aa2b5219Ssinsanction val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq) 103aa2b5219Ssinsanction wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel 104aa2b5219Ssinsanction } 105aa2b5219Ssinsanction } else { 106aa2b5219Ssinsanction enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ) 107aa2b5219Ssinsanction } 108aa2b5219Ssinsanction 109aa2b5219Ssinsanction enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency)) 110aa2b5219Ssinsanction .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) => 111aa2b5219Ssinsanction dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) => 112aa2b5219Ssinsanction if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 113aa2b5219Ssinsanction dp := (ldp << 2).asUInt | 2.U 114aa2b5219Ssinsanction else 115aa2b5219Ssinsanction dp := ldp << 1 116aa2b5219Ssinsanction } 117aa2b5219Ssinsanction } 118aa2b5219Ssinsanction 119aa2b5219Ssinsanction for (i <- 0 until params.numRegSrc) { 120aa2bcc31SzhanglyGit enqDelaySrcState(i) := entryReg.status.srcStatus(i).srcState | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i) 12153bf098fSxiaofeibao-xjtu enqDelayDataSources(i).value := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value) 122aa2b5219Ssinsanction if (params.hasIQWakeUp) { 123aa2b5219Ssinsanction val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR 124aa2b5219Ssinsanction val wakeUpOH = enqDelaySrcWakeUpByIQVec(i) 125acf41503Ssinsanction enqDelaySrcWakeUpL1ExuOH.get(i) := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq) 126aa2b5219Ssinsanction enqDelaySrcTimer.get(i) := Mux(wakeUpValid, 2.U, 3.U) 127eea4a3caSzhanglyGit enqDelaySrcLoadDependency(i) := Mux(enqDelaySrcWakeUpByIQVec(i).asUInt.orR, Mux1H(enqDelaySrcWakeUpByIQVec(i), enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency) 128eea4a3caSzhanglyGit } else { 129eea4a3caSzhanglyGit enqDelaySrcLoadDependency(i) := entryReg.status.srcStatus(i).srcLoadDependency 130aa2b5219Ssinsanction } 131aa2b5219Ssinsanction } 132aa2b5219Ssinsanction currentStatus := entryReg.status 133aa2b5219Ssinsanction when (enqDelayValidReg) { 134aa2bcc31SzhanglyGit currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) => 135aa2bcc31SzhanglyGit srcStatus.srcState := enqDelaySrcState(srcIdx) 136aa2bcc31SzhanglyGit srcStatus.dataSources := enqDelayDataSources(srcIdx) 137aa2bcc31SzhanglyGit srcStatus.srcTimer.foreach(_ := enqDelaySrcTimer.get(srcIdx)) 138eea4a3caSzhanglyGit srcStatus.srcLoadDependency := enqDelaySrcLoadDependency(srcIdx) 139aa2bcc31SzhanglyGit } 140aa2b5219Ssinsanction } 141aa2b5219Ssinsanction 142acf41503Ssinsanction if (params.hasIQWakeUp) { 143aa2bcc31SzhanglyGit currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach { 144acf41503Ssinsanction case ((currExuOH, regExuOH), enqDelayExuOH) => 145acf41503Ssinsanction currExuOH := 0.U.asTypeOf(currExuOH) 146acf41503Ssinsanction params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x))) 147acf41503Ssinsanction } 148acf41503Ssinsanction } 149acf41503Ssinsanction 150aa2bcc31SzhanglyGit EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true) 151e08589a5Ssinsanction 152397c0f33Ssinsanction //output 153df26db8aSsinsanction CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp) 1545db4956bSzhanglyGit} 1555db4956bSzhanglyGit 156e07131b2Ssinsanctionclass EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp) 1572d270511Ssinsanction with HasCircularQueuePtrHelper { 1582d270511Ssinsanction 159e07131b2Ssinsanction require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ") 1602d270511Ssinsanction 161e07131b2Ssinsanction EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate) 1622d270511Ssinsanction} 1632d270511Ssinsanction 1645db4956bSzhanglyGitobject EnqEntry { 165df26db8aSsinsanction def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 1665db4956bSzhanglyGit iqParams.schdType match { 167df26db8aSsinsanction case IntScheduler() => new EnqEntry(isComp) 1685db4956bSzhanglyGit case MemScheduler() => 169e07131b2Ssinsanction if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp) 170df26db8aSsinsanction else new EnqEntry(isComp) 171df26db8aSsinsanction case VfScheduler() => new EnqEntry(isComp) 1725db4956bSzhanglyGit case _ => null 1735db4956bSzhanglyGit } 1745db4956bSzhanglyGit } 1755db4956bSzhanglyGit}