15db4956bSzhanglyGitpackage xiangshan.backend.issue 25db4956bSzhanglyGit 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 45db4956bSzhanglyGitimport chisel3._ 55db4956bSzhanglyGitimport chisel3.util._ 64243aa09SsinceforYyimport utility.{HasCircularQueuePtrHelper, GatedValidRegNext} 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._ 149e12e8edScz4eimport xiangshan.mem.{SqPtr, LqPtr} 15*99ce5576Scz4eimport xiangshan.mem.Bundles.MemWaitUpdateReqBundle 165db4956bSzhanglyGit 175db4956bSzhanglyGit 185db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 195db4956bSzhanglyGit //input 20aa2bcc31SzhanglyGit val commonIn = new CommonInBundle 214fa640e4Ssinsanction val enqDelayIn1 = new EnqDelayInBundle 224fa640e4Ssinsanction val enqDelayIn2 = new EnqDelayInBundle 235db4956bSzhanglyGit 24aa2bcc31SzhanglyGit //output 25aa2bcc31SzhanglyGit val commonOut = new CommonOutBundle 26aa2bcc31SzhanglyGit 27aa2bcc31SzhanglyGit def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 285db4956bSzhanglyGit} 295db4956bSzhanglyGit 30df26db8aSsinsanctionclass EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 315db4956bSzhanglyGit val io = IO(new EnqEntryIO) 325db4956bSzhanglyGit 33aa2bcc31SzhanglyGit val common = Wire(new CommonWireBundle) 345db4956bSzhanglyGit val entryUpdate = Wire(new EntryBundle) 35aa2bcc31SzhanglyGit val entryRegNext = Wire(new EntryBundle) 36aa2b5219Ssinsanction val enqDelayValidRegNext= Wire(Bool()) 37aa2bcc31SzhanglyGit val hasWakeupIQ = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle)) 385db4956bSzhanglyGit 39aa2b5219Ssinsanction val currentStatus = Wire(new Status()) 40aa2b5219Ssinsanction val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState())) 41aa2b5219Ssinsanction val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource())) 42f57d73d6Ssinsanction val enqDelayExuSources = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuSource()))) 43ec49b127Ssinsanction val enqDelaySrcLoadDependency = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W)))) 444c2a845dSsinsanction val enqDelayUseRegCache = OptionWrapper(params.needReadRegCache, Wire(Vec(params.numRegSrc, Bool()))) 454c2a845dSsinsanction val enqDelayRegCacheIdx = OptionWrapper(params.needReadRegCache, Wire(Vec(params.numRegSrc, UInt(RegCacheIdxWidth.W)))) 46aa2b5219Ssinsanction 475db4956bSzhanglyGit //Reg 484243aa09SsinceforYy val validReg = GatedValidRegNext(common.validRegNext, false.B) 4956db494fSxiaofeibao-xjtu val entryReg = RegNext(entryRegNext) 504243aa09SsinceforYy val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B) 515db4956bSzhanglyGit 525db4956bSzhanglyGit //Wire 530dfdb52aSzhanglyGit CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true) 545db4956bSzhanglyGit 5528607074Ssinsanction when(io.commonIn.enq.valid) { 56c0beb497Sxiaofeibao assert(common.enqReady, s"${params.getIQName}'s EnqEntry is not ready when enq is valid\n") 5728607074Ssinsanction } 5828607074Ssinsanction 59aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 60aa2bcc31SzhanglyGit entryRegNext := io.commonIn.enq.bits 615db4956bSzhanglyGit }.otherwise { 625db4956bSzhanglyGit entryRegNext := entryUpdate 635db4956bSzhanglyGit } 645db4956bSzhanglyGit 65aa2bcc31SzhanglyGit when(io.commonIn.enq.valid && common.enqReady) { 66aa2b5219Ssinsanction enqDelayValidRegNext := true.B 67aa2b5219Ssinsanction }.otherwise { 68aa2b5219Ssinsanction enqDelayValidRegNext := false.B 69aa2b5219Ssinsanction } 70aa2b5219Ssinsanction 715db4956bSzhanglyGit if (params.hasIQWakeUp) { 72aa2bcc31SzhanglyGit ShiftLoadDependency(hasWakeupIQ.get) 730dfdb52aSzhanglyGit CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true) 745db4956bSzhanglyGit } 755db4956bSzhanglyGit 76aa2b5219Ssinsanction // enq delay wakeup 774fa640e4Ssinsanction val enqDelayOut1 = Wire(new EnqDelayOutBundle) 784fa640e4Ssinsanction val enqDelayOut2 = Wire(new EnqDelayOutBundle) 794fa640e4Ssinsanction EnqDelayWakeupConnect(io.enqDelayIn1, enqDelayOut1, entryReg.status, delay = 1) 804fa640e4Ssinsanction EnqDelayWakeupConnect(io.enqDelayIn2, enqDelayOut2, entryReg.status, delay = 2) 81aa2b5219Ssinsanction 82aa2b5219Ssinsanction for (i <- 0 until params.numRegSrc) { 834fa640e4Ssinsanction val enqDelay1WakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR 844fa640e4Ssinsanction val enqDelay1WakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i) 854fa640e4Ssinsanction val enqDelay2WakeUpOH = enqDelayOut2.srcWakeUpByIQVec(i) 86de111a36Ssinsanction val enqDelay1IsWakeupByMemIQ = enqDelay1WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _) 87de111a36Ssinsanction val enqDelay2IsWakeupByMemIQ = enqDelay2WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _) 8809d562eeSsinsanction val enqDelay2IsWakeupByVfIQ = enqDelay2WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isVfExeUnit).map(_._1).fold(false.B)(_ || _) 89de111a36Ssinsanction 90c4cabf18Ssinsanction if (params.inVfSchd && params.readVfRf && params.hasIQWakeUp) { 91c4cabf18Ssinsanction enqDelayDataSources(i).value := MuxCase(entryReg.status.srcStatus(i).dataSources.value, Seq( 92c4cabf18Ssinsanction (enqDelayOut1.srcWakeUpByIQ(i).asBool && !enqDelay1IsWakeupByMemIQ) -> DataSource.bypass, 93c4cabf18Ssinsanction (enqDelayOut1.srcWakeUpByIQ(i).asBool && enqDelay1IsWakeupByMemIQ) -> DataSource.bypass2, 94c4cabf18Ssinsanction (enqDelayOut2.srcWakeUpByIQ(i).asBool && !enqDelay2IsWakeupByMemIQ) -> DataSource.bypass2, 95c4cabf18Ssinsanction )) 96f57d73d6Ssinsanction enqDelayExuSources.get(i).value := Mux(enqDelay1WakeUpValid, 97f57d73d6Ssinsanction ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))), 98f57d73d6Ssinsanction ExuSource().fromExuOH(params, Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))))) 99c4cabf18Ssinsanction } 100c4cabf18Ssinsanction else if (params.inMemSchd && params.readVfRf && params.hasIQWakeUp) { 101c4cabf18Ssinsanction enqDelayDataSources(i).value := MuxCase(entryReg.status.srcStatus(i).dataSources.value, Seq( 102c4cabf18Ssinsanction enqDelayOut1.srcWakeUpByIQ(i).asBool -> DataSource.bypass, 10309d562eeSsinsanction (enqDelayOut2.srcWakeUpByIQ(i).asBool && enqDelay2IsWakeupByVfIQ) -> DataSource.bypass2, 104c4cabf18Ssinsanction )) 105f57d73d6Ssinsanction enqDelayExuSources.get(i).value := Mux(enqDelay1WakeUpValid, 106f57d73d6Ssinsanction ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))), 107f57d73d6Ssinsanction ExuSource().fromExuOH(params, Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))))) 108c4cabf18Ssinsanction } 109c4cabf18Ssinsanction else { 1104fa640e4Ssinsanction enqDelayDataSources(i).value := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value) 111aa2b5219Ssinsanction if (params.hasIQWakeUp) { 112f57d73d6Ssinsanction enqDelayExuSources.get(i).value := ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))) 1134fa640e4Ssinsanction } 1144fa640e4Ssinsanction } 1154fa640e4Ssinsanction 11691f31488Sxiaofeibao-xjtu enqDelaySrcState(i) := (!enqDelayOut1.srcCancelByLoad(i) & entryReg.status.srcStatus(i).srcState) | enqDelayOut1.srcWakeUpByWB(i) | enqDelayOut1.srcWakeUpByIQ(i) 1174fa640e4Ssinsanction if (params.hasIQWakeUp) { 118c4cabf18Ssinsanction enqDelaySrcLoadDependency(i) := Mux(enqDelay1WakeUpValid, Mux1H(enqDelay1WakeUpOH, enqDelayOut1.shiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency) 119eea4a3caSzhanglyGit } else { 120eea4a3caSzhanglyGit enqDelaySrcLoadDependency(i) := entryReg.status.srcStatus(i).srcLoadDependency 121aa2b5219Ssinsanction } 1224c2a845dSsinsanction 1234c2a845dSsinsanction if (params.needReadRegCache) { 1244c2a845dSsinsanction val enqDelay1WakeupSrcExuWriteRC = enqDelay1WakeUpOH.zip(io.enqDelayIn1.wakeUpFromIQ).filter(_._2.bits.params.needWriteRegCache) 125de4e991cSsinsanction val enqDelay1WakeupRC = enqDelay1WakeupSrcExuWriteRC.map(_._1).fold(false.B)(_ || _) && SrcType.isXp(entryReg.status.srcStatus(i).srcType) 1264c2a845dSsinsanction val enqDelay1WakeupRCIdx = Mux1H(enqDelay1WakeupSrcExuWriteRC.map(_._1), enqDelay1WakeupSrcExuWriteRC.map(_._2.bits.rcDest.get)) 1274c2a845dSsinsanction val enqDelay1ReplaceRC = enqDelay1WakeupSrcExuWriteRC.map(x => x._2.bits.rfWen && x._2.bits.rcDest.get === entryReg.status.srcStatus(i).regCacheIdx.get).fold(false.B)(_ || _) 1284c2a845dSsinsanction 129e311c278Ssinsanction enqDelayUseRegCache.get(i) := entryReg.status.srcStatus(i).useRegCache.get && !(enqDelayOut1.srcCancelByLoad(i) || enqDelay1ReplaceRC) || enqDelay1WakeupRC 1304c2a845dSsinsanction enqDelayRegCacheIdx.get(i) := Mux(enqDelay1WakeupRC, enqDelay1WakeupRCIdx, entryReg.status.srcStatus(i).regCacheIdx.get) 1314c2a845dSsinsanction } 132aa2b5219Ssinsanction } 1334fa640e4Ssinsanction 1344fa640e4Ssinsanction // current status 135aa2b5219Ssinsanction currentStatus := entryReg.status 136aa2b5219Ssinsanction when (enqDelayValidReg) { 137aa2bcc31SzhanglyGit currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) => 138aa2bcc31SzhanglyGit srcStatus.srcState := enqDelaySrcState(srcIdx) 139aa2bcc31SzhanglyGit srcStatus.dataSources := enqDelayDataSources(srcIdx) 140eea4a3caSzhanglyGit srcStatus.srcLoadDependency := enqDelaySrcLoadDependency(srcIdx) 1414c2a845dSsinsanction srcStatus.useRegCache.foreach(_ := enqDelayUseRegCache.get(srcIdx)) 1424c2a845dSsinsanction srcStatus.regCacheIdx.foreach(_ := enqDelayRegCacheIdx.get(srcIdx)) 143aa2bcc31SzhanglyGit } 144aa2b5219Ssinsanction } 145aa2b5219Ssinsanction 146acf41503Ssinsanction if (params.hasIQWakeUp) { 147f57d73d6Ssinsanction currentStatus.srcStatus.map(_.exuSources.get).zip(entryReg.status.srcStatus.map(_.exuSources.get)).zip(enqDelayExuSources.get).foreach { 148f57d73d6Ssinsanction case ((currExu, regExu), enqDelayExu) => 149f57d73d6Ssinsanction currExu := Mux(enqDelayValidReg, enqDelayExu, regExu) 150acf41503Ssinsanction } 151acf41503Ssinsanction } 152acf41503Ssinsanction 153e311c278Ssinsanction EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp) 154e08589a5Ssinsanction 155397c0f33Ssinsanction //output 156df26db8aSsinsanction CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp) 1575db4956bSzhanglyGit} 1585db4956bSzhanglyGit 159e07131b2Ssinsanctionclass EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp) 1602d270511Ssinsanction with HasCircularQueuePtrHelper { 1612d270511Ssinsanction 162e07131b2Ssinsanction require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ") 1632d270511Ssinsanction 164e07131b2Ssinsanction EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate) 1652d270511Ssinsanction} 1662d270511Ssinsanction 1675db4956bSzhanglyGitobject EnqEntry { 168df26db8aSsinsanction def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 1695db4956bSzhanglyGit iqParams.schdType match { 170df26db8aSsinsanction case IntScheduler() => new EnqEntry(isComp) 17160f0c5aeSxiaofeibao case FpScheduler() => new EnqEntry(isComp) 1725db4956bSzhanglyGit case MemScheduler() => 173e07131b2Ssinsanction if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp) 174df26db8aSsinsanction else new EnqEntry(isComp) 175df26db8aSsinsanction case VfScheduler() => new EnqEntry(isComp) 1765db4956bSzhanglyGit case _ => null 1775db4956bSzhanglyGit } 1785db4956bSzhanglyGit } 1795db4956bSzhanglyGit} 180