1*0a7d1d5cSxiaofeibao/*************************************************************************************** 2*0a7d1d5cSxiaofeibao* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*0a7d1d5cSxiaofeibao* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*0a7d1d5cSxiaofeibao* 5*0a7d1d5cSxiaofeibao* XiangShan is licensed under Mulan PSL v2. 6*0a7d1d5cSxiaofeibao* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*0a7d1d5cSxiaofeibao* You may obtain a copy of Mulan PSL v2 at: 8*0a7d1d5cSxiaofeibao* http://license.coscl.org.cn/MulanPSL2 9*0a7d1d5cSxiaofeibao* 10*0a7d1d5cSxiaofeibao* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*0a7d1d5cSxiaofeibao* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*0a7d1d5cSxiaofeibao* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*0a7d1d5cSxiaofeibao* 14*0a7d1d5cSxiaofeibao* See the Mulan PSL v2 for more details. 15*0a7d1d5cSxiaofeibao***************************************************************************************/ 16*0a7d1d5cSxiaofeibao 17*0a7d1d5cSxiaofeibaopackage xiangshan.backend.dispatch 18*0a7d1d5cSxiaofeibao 19*0a7d1d5cSxiaofeibaoimport org.chipsalliance.cde.config.Parameters 20*0a7d1d5cSxiaofeibaoimport chisel3._ 21*0a7d1d5cSxiaofeibaoimport chisel3.util._ 22*0a7d1d5cSxiaofeibaoimport utility._ 23*0a7d1d5cSxiaofeibaoimport xiangshan.ExceptionNO._ 24*0a7d1d5cSxiaofeibaoimport xiangshan._ 25*0a7d1d5cSxiaofeibaoimport xiangshan.backend.MemCoreTopDownIO 26*0a7d1d5cSxiaofeibaoimport xiangshan.backend.rob.{RobDispatchTopDownIO, RobEnqIO} 27*0a7d1d5cSxiaofeibaoimport xiangshan.mem.mdp._ 28*0a7d1d5cSxiaofeibaoimport xiangshan.mem.{HasVLSUParameters, _} 29*0a7d1d5cSxiaofeibaoimport xiangshan.backend.Bundles.{DecodedInst, DynInst, ExuOH, ExuVec, IssueQueueIQWakeUpBundle} 30*0a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.{FuConfig, FuType} 31*0a7d1d5cSxiaofeibaoimport xiangshan.backend.rename.BusyTable 32*0a7d1d5cSxiaofeibaoimport chisel3.util.experimental.decode._ 33*0a7d1d5cSxiaofeibaoimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 34*0a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.{FuConfig, FuType} 35*0a7d1d5cSxiaofeibaoimport xiangshan.backend.rename.BusyTableReadIO 36*0a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.DataConfig._ 37*0a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.WbConfig._ 38*0a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.DataSource 39*0a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.WbConfig.VfWB 40*0a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.FuType.FuTypeOrR 41*0a7d1d5cSxiaofeibaoimport xiangshan.backend.dispatch.Dispatch2IqFpImp 42*0a7d1d5cSxiaofeibaoimport xiangshan.backend.regcache.{RCTagTableReadPort, RegCacheTagTable} 43*0a7d1d5cSxiaofeibao 44*0a7d1d5cSxiaofeibao 45*0a7d1d5cSxiaofeibao// TODO delete trigger message from frontend to iq 46*0a7d1d5cSxiaofeibaoclass NewDispatch(implicit p: Parameters) extends XSModule with HasPerfEvents with HasVLSUParameters { 47*0a7d1d5cSxiaofeibao // std IQ donot need dispatch, only copy sta IQ, but need sta IQ's ready && std IQ's ready 48*0a7d1d5cSxiaofeibao val allIssueParams = backendParams.allIssueParams.filter(_.StdCnt == 0) 49*0a7d1d5cSxiaofeibao val allExuParams = allIssueParams.map(_.exuBlockParams).flatten 50*0a7d1d5cSxiaofeibao val allFuConfigs = allExuParams.map(_.fuConfigs).flatten.toSet.toSeq 51*0a7d1d5cSxiaofeibao val sortedFuConfigs = allFuConfigs.sortBy(_.fuType.id) 52*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allExuParams.map(_.name)}") 53*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allFuConfigs.map(_.name)}") 54*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allFuConfigs.map(_.fuType.id)}") 55*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${sortedFuConfigs.map(_.name)}") 56*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${sortedFuConfigs.map(_.fuType.id)}") 57*0a7d1d5cSxiaofeibao val fuConfigsInIssueParams = allIssueParams.map(_.allExuParams.map(_.fuConfigs).flatten.toSet.toSeq) 58*0a7d1d5cSxiaofeibao val fuMapIQIdx = sortedFuConfigs.map( fu => { 59*0a7d1d5cSxiaofeibao val fuInIQIdx = fuConfigsInIssueParams.zipWithIndex.filter { case (f, i) => f.contains(fu) }.map(_._2) 60*0a7d1d5cSxiaofeibao (fu -> fuInIQIdx) 61*0a7d1d5cSxiaofeibao } 62*0a7d1d5cSxiaofeibao ) 63*0a7d1d5cSxiaofeibao fuMapIQIdx.map { case (fu, iqidx) => 64*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${fu.name} $iqidx") 65*0a7d1d5cSxiaofeibao } 66*0a7d1d5cSxiaofeibao val sameIQIdxFus = fuMapIQIdx.map{ case (fu, iqidx) => 67*0a7d1d5cSxiaofeibao fuMapIQIdx.filter(_._2 == iqidx).map(_._1) -> iqidx 68*0a7d1d5cSxiaofeibao }.toSet.toSeq 69*0a7d1d5cSxiaofeibao val needMultiIQ = sameIQIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size > 1) 70*0a7d1d5cSxiaofeibao val needSingleIQ = sameIQIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size == 1) 71*0a7d1d5cSxiaofeibao needMultiIQ.map { case (fus, iqidx) => 72*0a7d1d5cSxiaofeibao println(s"[NewDispatch] needMultiIQ: ${fus.map(_.name)} $iqidx") 73*0a7d1d5cSxiaofeibao } 74*0a7d1d5cSxiaofeibao needSingleIQ.map { case (fus, iqidx) => 75*0a7d1d5cSxiaofeibao println(s"[NewDispatch] needSingleIQ: ${fus.map(_.name)} $iqidx") 76*0a7d1d5cSxiaofeibao } 77*0a7d1d5cSxiaofeibao val fuConfigsInExuParams = allExuParams.map(_.fuConfigs) 78*0a7d1d5cSxiaofeibao val fuMapExuIdx = sortedFuConfigs.map { case fu => { 79*0a7d1d5cSxiaofeibao val fuInExuIdx = fuConfigsInExuParams.zipWithIndex.filter { case (f, i) => f.contains(fu) }.map(_._2) 80*0a7d1d5cSxiaofeibao (fu -> fuInExuIdx) 81*0a7d1d5cSxiaofeibao } 82*0a7d1d5cSxiaofeibao } 83*0a7d1d5cSxiaofeibao val sameExuIdxFus = fuMapExuIdx.map { case (fu, exuidx) => 84*0a7d1d5cSxiaofeibao fuMapExuIdx.filter(_._2 == exuidx).map(_._1) -> exuidx 85*0a7d1d5cSxiaofeibao }.toSet.toSeq 86*0a7d1d5cSxiaofeibao val needMultiExu = sameExuIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size > 1).filter{ x => 87*0a7d1d5cSxiaofeibao x._1.map(y => fuMapIQIdx.filter(_._1 == y).head._2.size > 1).reduce(_ && _) 88*0a7d1d5cSxiaofeibao } 89*0a7d1d5cSxiaofeibao 90*0a7d1d5cSxiaofeibao val exuNum = allExuParams.size 91*0a7d1d5cSxiaofeibao val maxIQSize = allIssueParams.map(_.numEntries).max 92*0a7d1d5cSxiaofeibao val IQEnqSum = allIssueParams.map(_.numEnq).sum 93*0a7d1d5cSxiaofeibao 94*0a7d1d5cSxiaofeibao val io = IO(new Bundle { 95*0a7d1d5cSxiaofeibao // from rename 96*0a7d1d5cSxiaofeibao val renameIn = Vec(RenameWidth, Flipped(ValidIO(new DecodedInst))) 97*0a7d1d5cSxiaofeibao val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new DynInst))) 98*0a7d1d5cSxiaofeibao val toRenameAllFire = Output(Bool()) 99*0a7d1d5cSxiaofeibao // enq Rob 100*0a7d1d5cSxiaofeibao val enqRob = Flipped(new RobEnqIO) 101*0a7d1d5cSxiaofeibao // IssueQueues 102*0a7d1d5cSxiaofeibao val IQValidNumVec = Vec(exuNum, Input(UInt(maxIQSize.U.getWidth.W))) 103*0a7d1d5cSxiaofeibao val toIssueQueues = Vec(IQEnqSum, DecoupledIO(new DynInst)) 104*0a7d1d5cSxiaofeibao // to busyTable 105*0a7d1d5cSxiaofeibao // set preg state to ready (write back regfile) 106*0a7d1d5cSxiaofeibao val wbPregsInt = Vec(backendParams.numPregWb(IntData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 107*0a7d1d5cSxiaofeibao val wbPregsFp = Vec(backendParams.numPregWb(FpData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 108*0a7d1d5cSxiaofeibao val wbPregsVec = Vec(backendParams.numPregWb(VecData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 109*0a7d1d5cSxiaofeibao val wbPregsV0 = Vec(backendParams.numPregWb(V0Data()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 110*0a7d1d5cSxiaofeibao val wbPregsVl = Vec(backendParams.numPregWb(VlData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 111*0a7d1d5cSxiaofeibao val wakeUpAll = new Bundle { 112*0a7d1d5cSxiaofeibao val wakeUpInt: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.intSchdParams.get.genIQWakeUpOutValidBundle) 113*0a7d1d5cSxiaofeibao val wakeUpFp: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.fpSchdParams.get.genIQWakeUpOutValidBundle) 114*0a7d1d5cSxiaofeibao val wakeUpVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.vfSchdParams.get.genIQWakeUpOutValidBundle) 115*0a7d1d5cSxiaofeibao val wakeUpMem: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.memSchdParams.get.genIQWakeUpOutValidBundle) 116*0a7d1d5cSxiaofeibao } 117*0a7d1d5cSxiaofeibao val og0Cancel = Input(ExuVec()) 118*0a7d1d5cSxiaofeibao val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 119*0a7d1d5cSxiaofeibao // from MemBlock 120*0a7d1d5cSxiaofeibao val fromMem = new Bundle { 121*0a7d1d5cSxiaofeibao val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 122*0a7d1d5cSxiaofeibao val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 123*0a7d1d5cSxiaofeibao val lqDeqPtr = Input(new LqPtr) 124*0a7d1d5cSxiaofeibao val sqDeqPtr = Input(new SqPtr) 125*0a7d1d5cSxiaofeibao // from lsq 126*0a7d1d5cSxiaofeibao val lqCancelCnt = Input(UInt(log2Up(VirtualLoadQueueSize + 1).W)) 127*0a7d1d5cSxiaofeibao val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 128*0a7d1d5cSxiaofeibao } 129*0a7d1d5cSxiaofeibao //toMem 130*0a7d1d5cSxiaofeibao val toMem = new Bundle { 131*0a7d1d5cSxiaofeibao val lsqEnqIO = Flipped(new LsqEnqIO) 132*0a7d1d5cSxiaofeibao } 133*0a7d1d5cSxiaofeibao // redirect 134*0a7d1d5cSxiaofeibao val redirect = Flipped(ValidIO(new Redirect)) 135*0a7d1d5cSxiaofeibao // singleStep 136*0a7d1d5cSxiaofeibao val singleStep = Input(Bool()) 137*0a7d1d5cSxiaofeibao // lfst 138*0a7d1d5cSxiaofeibao val lfst = new DispatchLFSTIO 139*0a7d1d5cSxiaofeibao 140*0a7d1d5cSxiaofeibao // perf only 141*0a7d1d5cSxiaofeibao val robHead = Input(new DynInst) 142*0a7d1d5cSxiaofeibao val stallReason = Flipped(new StallReasonIO(RenameWidth)) 143*0a7d1d5cSxiaofeibao val lqCanAccept = Input(Bool()) 144*0a7d1d5cSxiaofeibao val sqCanAccept = Input(Bool()) 145*0a7d1d5cSxiaofeibao val robHeadNotReady = Input(Bool()) 146*0a7d1d5cSxiaofeibao val robFull = Input(Bool()) 147*0a7d1d5cSxiaofeibao val debugTopDown = new Bundle { 148*0a7d1d5cSxiaofeibao val fromRob = Flipped(new RobDispatchTopDownIO) 149*0a7d1d5cSxiaofeibao val fromCore = new CoreDispatchTopDownIO 150*0a7d1d5cSxiaofeibao } 151*0a7d1d5cSxiaofeibao }) 152*0a7d1d5cSxiaofeibao // Deq for std's IQ is not assigned in Dispatch2Iq, so add one more src for it. 153*0a7d1d5cSxiaofeibao val issueBlockParams = backendParams.allIssueParams 154*0a7d1d5cSxiaofeibao val renameIn = io.renameIn 155*0a7d1d5cSxiaofeibao val fromRename = io.fromRename 156*0a7d1d5cSxiaofeibao io.toRenameAllFire := io.fromRename.map(x => !x.valid || x.fire).reduce(_ && _) 157*0a7d1d5cSxiaofeibao val fromRenameUpdate = Wire(Vec(RenameWidth, Flipped(ValidIO(new DynInst)))) 158*0a7d1d5cSxiaofeibao fromRenameUpdate := fromRename 159*0a7d1d5cSxiaofeibao val renameWidth = io.fromRename.size 160*0a7d1d5cSxiaofeibao val issueQueueCount = io.IQValidNumVec 161*0a7d1d5cSxiaofeibao val issueQueueNum = allIssueParams.size 162*0a7d1d5cSxiaofeibao // int fp vec v0 vl 163*0a7d1d5cSxiaofeibao val numRegType = 5 164*0a7d1d5cSxiaofeibao val idxRegTypeInt = allFuConfigs.map(x => { 165*0a7d1d5cSxiaofeibao x.srcData.map(xx => { 166*0a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => IntRegSrcDataSet.contains(y._1)).map(_._2) 167*0a7d1d5cSxiaofeibao }).flatten 168*0a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 169*0a7d1d5cSxiaofeibao val idxRegTypeFp = allFuConfigs.map(x => { 170*0a7d1d5cSxiaofeibao x.srcData.map(xx => { 171*0a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => FpRegSrcDataSet.contains(y._1)).map(_._2) 172*0a7d1d5cSxiaofeibao }).flatten 173*0a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 174*0a7d1d5cSxiaofeibao val idxRegTypeVec = allFuConfigs.map(x => { 175*0a7d1d5cSxiaofeibao x.srcData.map(xx => { 176*0a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => VecRegSrcDataSet.contains(y._1)).map(_._2) 177*0a7d1d5cSxiaofeibao }).flatten 178*0a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 179*0a7d1d5cSxiaofeibao val idxRegTypeV0 = allFuConfigs.map(x => { 180*0a7d1d5cSxiaofeibao x.srcData.map(xx => { 181*0a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => V0RegSrcDataSet.contains(y._1)).map(_._2) 182*0a7d1d5cSxiaofeibao }).flatten 183*0a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 184*0a7d1d5cSxiaofeibao val idxRegTypeVl = allFuConfigs.map(x => { 185*0a7d1d5cSxiaofeibao x.srcData.map(xx => { 186*0a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => VlRegSrcDataSet.contains(y._1)).map(_._2) 187*0a7d1d5cSxiaofeibao }).flatten 188*0a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 189*0a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeInt: $idxRegTypeInt") 190*0a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeFp: $idxRegTypeFp") 191*0a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeVec: $idxRegTypeVec") 192*0a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeV0: $idxRegTypeV0") 193*0a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeVl: $idxRegTypeVl") 194*0a7d1d5cSxiaofeibao val numRegSrc: Int = issueBlockParams.map(_.exuBlockParams.map( 195*0a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numRegSrc + 1 else x.numRegSrc 196*0a7d1d5cSxiaofeibao ).max).max 197*0a7d1d5cSxiaofeibao 198*0a7d1d5cSxiaofeibao val numRegSrcInt: Int = issueBlockParams.map(_.exuBlockParams.map( 199*0a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numIntSrc + 1 else x.numIntSrc 200*0a7d1d5cSxiaofeibao ).max).max 201*0a7d1d5cSxiaofeibao val numRegSrcFp: Int = issueBlockParams.map(_.exuBlockParams.map( 202*0a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numFpSrc + 1 else x.numFpSrc 203*0a7d1d5cSxiaofeibao ).max).max 204*0a7d1d5cSxiaofeibao val numRegSrcVf: Int = issueBlockParams.map(_.exuBlockParams.map( 205*0a7d1d5cSxiaofeibao x => x.numVecSrc 206*0a7d1d5cSxiaofeibao ).max).max 207*0a7d1d5cSxiaofeibao val numRegSrcV0: Int = issueBlockParams.map(_.exuBlockParams.map( 208*0a7d1d5cSxiaofeibao x => x.numV0Src 209*0a7d1d5cSxiaofeibao ).max).max 210*0a7d1d5cSxiaofeibao val numRegSrcVl: Int = issueBlockParams.map(_.exuBlockParams.map( 211*0a7d1d5cSxiaofeibao x => x.numVlSrc 212*0a7d1d5cSxiaofeibao ).max).max 213*0a7d1d5cSxiaofeibao 214*0a7d1d5cSxiaofeibao println(s"[Dispatch2Iq] numRegSrc: ${numRegSrc}, numRegSrcInt: ${numRegSrcInt}, numRegSrcFp: ${numRegSrcFp}, " + 215*0a7d1d5cSxiaofeibao s"numRegSrcVf: ${numRegSrcVf}, numRegSrcV0: ${numRegSrcV0}, numRegSrcVl: ${numRegSrcVl}") 216*0a7d1d5cSxiaofeibao 217*0a7d1d5cSxiaofeibao // RegCacheTagTable Module 218*0a7d1d5cSxiaofeibao val rcTagTable = Module(new RegCacheTagTable(numRegSrcInt * renameWidth)) 219*0a7d1d5cSxiaofeibao // BusyTable Modules 220*0a7d1d5cSxiaofeibao val intBusyTable = Module(new BusyTable(numRegSrcInt * renameWidth, backendParams.numPregWb(IntData()), IntPhyRegs, IntWB())) 221*0a7d1d5cSxiaofeibao val fpBusyTable = Module(new BusyTable(numRegSrcFp * renameWidth, backendParams.numPregWb(FpData()), FpPhyRegs, FpWB())) 222*0a7d1d5cSxiaofeibao val vecBusyTable = Module(new BusyTable(numRegSrcVf * renameWidth, backendParams.numPregWb(VecData()), VfPhyRegs, VfWB())) 223*0a7d1d5cSxiaofeibao val v0BusyTable = Module(new BusyTable(numRegSrcV0 * renameWidth, backendParams.numPregWb(V0Data()), V0PhyRegs, V0WB())) 224*0a7d1d5cSxiaofeibao val vlBusyTable = Module(new BusyTable(numRegSrcVl * renameWidth, backendParams.numPregWb(VlData()), VlPhyRegs, VlWB())) 225*0a7d1d5cSxiaofeibao val busyTables = Seq(intBusyTable, fpBusyTable, vecBusyTable, v0BusyTable, vlBusyTable) 226*0a7d1d5cSxiaofeibao val wbPregs = Seq(io.wbPregsInt, io.wbPregsFp, io.wbPregsVec, io.wbPregsV0, io.wbPregsVl) 227*0a7d1d5cSxiaofeibao val idxRegType = Seq(idxRegTypeInt, idxRegTypeFp, idxRegTypeVec, idxRegTypeV0, idxRegTypeVl) 228*0a7d1d5cSxiaofeibao val allocPregsValid = Wire(Vec(busyTables.size, Vec(RenameWidth, Bool()))) 229*0a7d1d5cSxiaofeibao allocPregsValid(0) := VecInit(fromRename.map(x => x.valid && x.bits.rfWen && !x.bits.eliminatedMove)) 230*0a7d1d5cSxiaofeibao allocPregsValid(1) := VecInit(fromRename.map(x => x.valid && x.bits.fpWen)) 231*0a7d1d5cSxiaofeibao allocPregsValid(2) := VecInit(fromRename.map(x => x.valid && x.bits.vecWen)) 232*0a7d1d5cSxiaofeibao allocPregsValid(3) := VecInit(fromRename.map(x => x.valid && x.bits.v0Wen)) 233*0a7d1d5cSxiaofeibao allocPregsValid(4) := VecInit(fromRename.map(x => x.valid && x.bits.vlWen)) 234*0a7d1d5cSxiaofeibao val allocPregs = Wire(Vec(busyTables.size, Vec(RenameWidth, ValidIO(UInt(PhyRegIdxWidth.W))))) 235*0a7d1d5cSxiaofeibao allocPregs.zip(allocPregsValid).map(x =>{ 236*0a7d1d5cSxiaofeibao x._1.zip(x._2).zipWithIndex.map{case ((sink, source), i) => { 237*0a7d1d5cSxiaofeibao sink.valid := source 238*0a7d1d5cSxiaofeibao sink.bits := fromRename(i).bits.pdest 239*0a7d1d5cSxiaofeibao }} 240*0a7d1d5cSxiaofeibao }) 241*0a7d1d5cSxiaofeibao val wakeUp = io.wakeUpAll.wakeUpInt ++ io.wakeUpAll.wakeUpFp ++ io.wakeUpAll.wakeUpVec ++ io.wakeUpAll.wakeUpMem 242*0a7d1d5cSxiaofeibao busyTables.zip(wbPregs).zip(allocPregs).map{ case ((b, w), a) => { 243*0a7d1d5cSxiaofeibao b.io.wakeUpInt := io.wakeUpAll.wakeUpInt 244*0a7d1d5cSxiaofeibao b.io.wakeUpFp := io.wakeUpAll.wakeUpFp 245*0a7d1d5cSxiaofeibao b.io.wakeUpVec := io.wakeUpAll.wakeUpVec 246*0a7d1d5cSxiaofeibao b.io.wakeUpMem := io.wakeUpAll.wakeUpMem 247*0a7d1d5cSxiaofeibao b.io.og0Cancel := io.og0Cancel 248*0a7d1d5cSxiaofeibao b.io.ldCancel := io.ldCancel 249*0a7d1d5cSxiaofeibao b.io.wbPregs := w 250*0a7d1d5cSxiaofeibao b.io.allocPregs := a 251*0a7d1d5cSxiaofeibao }} 252*0a7d1d5cSxiaofeibao rcTagTable.io.allocPregs.zip(allocPregs(0)).map(x => x._1 := x._2) 253*0a7d1d5cSxiaofeibao rcTagTable.io.wakeupFromIQ := io.wakeUpAll.wakeUpInt ++ io.wakeUpAll.wakeUpMem 254*0a7d1d5cSxiaofeibao rcTagTable.io.og0Cancel := io.og0Cancel 255*0a7d1d5cSxiaofeibao rcTagTable.io.ldCancel := io.ldCancel 256*0a7d1d5cSxiaofeibao busyTables.zip(idxRegType).zipWithIndex.map { case ((b, idxseq), i) => { 257*0a7d1d5cSxiaofeibao val readAddr = VecInit(fromRename.map(x => x.bits.psrc.zipWithIndex.filter(xx => idxseq.contains(xx._2)).map(_._1)).flatten) 258*0a7d1d5cSxiaofeibao val readValid = VecInit(fromRename.map(x => x.bits.psrc.zipWithIndex.filter(xx => idxseq.contains(xx._2)).map(y => x.valid && SrcType.isXp(x.bits.srcType(y._2)))).flatten) 259*0a7d1d5cSxiaofeibao b.io.read.map(_.req).zip(readAddr).map(x => x._1 := x._2) 260*0a7d1d5cSxiaofeibao // only int src need srcLoadDependency, src0 src1 261*0a7d1d5cSxiaofeibao if (i == 0) { 262*0a7d1d5cSxiaofeibao val srcLoadDependencyUpdate = fromRenameUpdate.map(x => x.bits.srcLoadDependency.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 263*0a7d1d5cSxiaofeibao val srcType = fromRenameUpdate.map(x => x.bits.srcType.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 264*0a7d1d5cSxiaofeibao // for std, int src need srcLoadDependency, fp src donot need srcLoadDependency 265*0a7d1d5cSxiaofeibao srcLoadDependencyUpdate.lazyZip(b.io.read.map(_.loadDependency)).lazyZip(srcType).map{ case (sink, source, srctype) => 266*0a7d1d5cSxiaofeibao sink := Mux(SrcType.isXp(srctype), source, 0.U.asTypeOf(sink)) 267*0a7d1d5cSxiaofeibao } 268*0a7d1d5cSxiaofeibao // only int src need rcTag 269*0a7d1d5cSxiaofeibao val rcTagUpdate = fromRenameUpdate.map(x => x.bits.regCacheIdx.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 270*0a7d1d5cSxiaofeibao rcTagUpdate.zip(rcTagTable.io.readPorts.map(_.addr)).map(x => x._1 := x._2) 271*0a7d1d5cSxiaofeibao val useRegCacheUpdate = fromRenameUpdate.map(x => x.bits.useRegCache.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 272*0a7d1d5cSxiaofeibao useRegCacheUpdate.zip(rcTagTable.io.readPorts.map(_.valid)).map(x => x._1 := x._2) 273*0a7d1d5cSxiaofeibao rcTagTable.io.readPorts.map(_.ren).zip(readValid).map(x => x._1 := x._2) 274*0a7d1d5cSxiaofeibao rcTagTable.io.readPorts.map(_.tag).zip(readAddr).map(x => x._1 := x._2) 275*0a7d1d5cSxiaofeibao } 276*0a7d1d5cSxiaofeibao }} 277*0a7d1d5cSxiaofeibao val allSrcState = Wire(Vec(renameWidth, Vec(numRegSrc, Vec(numRegType, Bool())))) 278*0a7d1d5cSxiaofeibao for (i <- 0 until renameWidth){ 279*0a7d1d5cSxiaofeibao for (j <- 0 until numRegSrc){ 280*0a7d1d5cSxiaofeibao for (k <- 0 until numRegType){ 281*0a7d1d5cSxiaofeibao if (!idxRegType(k).contains(j)) { 282*0a7d1d5cSxiaofeibao allSrcState(i)(j)(k) := false.B 283*0a7d1d5cSxiaofeibao } 284*0a7d1d5cSxiaofeibao else { 285*0a7d1d5cSxiaofeibao val readidx = i * idxRegType(k).size + idxRegType(k).indexOf(j) 286*0a7d1d5cSxiaofeibao val readEn = k match { 287*0a7d1d5cSxiaofeibao case 0 => SrcType.isXp(fromRename(i).bits.srcType(j)) 288*0a7d1d5cSxiaofeibao case 1 => SrcType.isFp(fromRename(i).bits.srcType(j)) 289*0a7d1d5cSxiaofeibao case 2 => SrcType.isVp(fromRename(i).bits.srcType(j)) 290*0a7d1d5cSxiaofeibao case 3 => SrcType.isV0(fromRename(i).bits.srcType(j)) 291*0a7d1d5cSxiaofeibao case 4 => true.B 292*0a7d1d5cSxiaofeibao } 293*0a7d1d5cSxiaofeibao allSrcState(i)(j)(k) := readEn && busyTables(k).io.read(readidx).resp || SrcType.isImm(fromRename(i).bits.srcType(j)) 294*0a7d1d5cSxiaofeibao } 295*0a7d1d5cSxiaofeibao } 296*0a7d1d5cSxiaofeibao } 297*0a7d1d5cSxiaofeibao } 298*0a7d1d5cSxiaofeibao 299*0a7d1d5cSxiaofeibao 300*0a7d1d5cSxiaofeibao 301*0a7d1d5cSxiaofeibao val minIQSelAll = Wire(Vec(needMultiExu.size, Vec(renameWidth, Vec(issueQueueNum, Bool())))) 302*0a7d1d5cSxiaofeibao needMultiExu.zipWithIndex.map{ case ((fus, exuidx), needMultiExuidx) => { 303*0a7d1d5cSxiaofeibao val suffix = fus.map(_.name).mkString("_") 304*0a7d1d5cSxiaofeibao val iqNum = exuidx.size 305*0a7d1d5cSxiaofeibao val iqidx = allIssueParams.map(_.exuBlockParams.map(_.fuConfigs).flatten.toSet.toSeq).zipWithIndex.filter{x => fus.toSet.subsetOf(x._1.toSet)}.map(_._2) 306*0a7d1d5cSxiaofeibao println(s"[NewDispatch] ${fus.map(_.name)};iqidx:$iqidx;exuIdx:$exuidx") 307*0a7d1d5cSxiaofeibao val compareMatrix = Wire(Vec(iqNum, Vec(iqNum, Bool()))).suggestName(s"compareMatrix_$suffix") 308*0a7d1d5cSxiaofeibao for (i <- 0 until iqNum) { 309*0a7d1d5cSxiaofeibao for (j <- 0 until iqNum) { 310*0a7d1d5cSxiaofeibao if (i == j) compareMatrix(i)(j) := false.B 311*0a7d1d5cSxiaofeibao else if (i < j) compareMatrix(i)(j) := issueQueueCount(exuidx(i)) < issueQueueCount(exuidx(j)) 312*0a7d1d5cSxiaofeibao else compareMatrix(i)(j) := !compareMatrix(j)(i) 313*0a7d1d5cSxiaofeibao } 314*0a7d1d5cSxiaofeibao } 315*0a7d1d5cSxiaofeibao val IQSort = Reg(Vec(iqNum, Vec(iqNum, Bool()))).suggestName(s"IQSort_$suffix}") 316*0a7d1d5cSxiaofeibao for (i <- 0 until iqNum){ 317*0a7d1d5cSxiaofeibao // i = 0 minimum iq, i = iqNum - 1 -> maximum iq 318*0a7d1d5cSxiaofeibao IQSort(i) := compareMatrix.map(x => PopCount(x) === (iqNum - 1 - i).U) 319*0a7d1d5cSxiaofeibao } 320*0a7d1d5cSxiaofeibao val minIQSel = Wire(Vec(renameWidth, Vec(issueQueueNum, Bool()))).suggestName(s"minIQSel_$suffix") 321*0a7d1d5cSxiaofeibao for (i <- 0 until renameWidth){ 322*0a7d1d5cSxiaofeibao val minIQSel_ith = IQSort(i % iqNum) 323*0a7d1d5cSxiaofeibao println(s"minIQSel_${i}th_$suffix = IQSort(${i % iqNum})") 324*0a7d1d5cSxiaofeibao for (j <- 0 until issueQueueNum){ 325*0a7d1d5cSxiaofeibao minIQSel(i)(j) := false.B 326*0a7d1d5cSxiaofeibao if (iqidx.contains(j)){ 327*0a7d1d5cSxiaofeibao minIQSel(i)(j) := minIQSel_ith(iqidx.indexOf(j)) 328*0a7d1d5cSxiaofeibao println(s"minIQSel_${suffix}_${i}_${j} = minIQSel_ith(iqidx.indexOf(${j}))") 329*0a7d1d5cSxiaofeibao } 330*0a7d1d5cSxiaofeibao } 331*0a7d1d5cSxiaofeibao } 332*0a7d1d5cSxiaofeibao minIQSelAll(needMultiExuidx) := minIQSel 333*0a7d1d5cSxiaofeibao if (backendParams.debugEn){ 334*0a7d1d5cSxiaofeibao dontTouch(compareMatrix) 335*0a7d1d5cSxiaofeibao dontTouch(IQSort) 336*0a7d1d5cSxiaofeibao dontTouch(minIQSel) 337*0a7d1d5cSxiaofeibao } 338*0a7d1d5cSxiaofeibao } 339*0a7d1d5cSxiaofeibao } 340*0a7d1d5cSxiaofeibao val fuConfigSeq = needMultiExu.map(_._1) 341*0a7d1d5cSxiaofeibao val fuTypeOH = Wire(Vec(renameWidth, Vec(needMultiExu.size, Bool()))) 342*0a7d1d5cSxiaofeibao fuTypeOH.zip(renameIn).map{ case(oh, in) => { 343*0a7d1d5cSxiaofeibao oh := fuConfigSeq.map(x => x.map(xx => in.bits.fuType(xx.fuType.id)).reduce(_ || _) && in.valid) 344*0a7d1d5cSxiaofeibao } 345*0a7d1d5cSxiaofeibao } 346*0a7d1d5cSxiaofeibao // not count itself 347*0a7d1d5cSxiaofeibao val popFuTypeOH = Wire(Vec(renameWidth, Vec(needMultiExu.size, UInt((renameWidth-1).U.getWidth.W)))) 348*0a7d1d5cSxiaofeibao popFuTypeOH.zipWithIndex.map{ case (pop, idx) => { 349*0a7d1d5cSxiaofeibao if (idx == 0){ 350*0a7d1d5cSxiaofeibao pop := 0.U.asTypeOf(pop) 351*0a7d1d5cSxiaofeibao } 352*0a7d1d5cSxiaofeibao else { 353*0a7d1d5cSxiaofeibao pop.zipWithIndex.map{ case (p, i) => { 354*0a7d1d5cSxiaofeibao p := PopCount(fuTypeOH.take(idx).map(x => x(i))) 355*0a7d1d5cSxiaofeibao } 356*0a7d1d5cSxiaofeibao } 357*0a7d1d5cSxiaofeibao } 358*0a7d1d5cSxiaofeibao }} 359*0a7d1d5cSxiaofeibao val uopSelIQ = Reg(Vec(renameWidth, Vec(issueQueueNum, Bool()))) 360*0a7d1d5cSxiaofeibao val fuTypeOHSingle = Wire(Vec(renameWidth, Vec(needSingleIQ.size, Bool()))) 361*0a7d1d5cSxiaofeibao fuTypeOHSingle.zip(renameIn).map{ case (oh, in) => { 362*0a7d1d5cSxiaofeibao oh := needSingleIQ.map(_._1).map(x => x.map(xx => in.valid && in.bits.fuType(xx.fuType.id)).reduce(_ || _)) 363*0a7d1d5cSxiaofeibao }} 364*0a7d1d5cSxiaofeibao val uopSelIQSingle = Wire(Vec(needSingleIQ.size, Vec(issueQueueNum, Bool()))) 365*0a7d1d5cSxiaofeibao uopSelIQSingle := VecInit(needSingleIQ.map(_._2).flatten.map(x => VecInit((1.U(issueQueueNum.W) << x)(issueQueueNum-1, 0).asBools))) 366*0a7d1d5cSxiaofeibao uopSelIQ.zipWithIndex.map{ case (u, i) => { 367*0a7d1d5cSxiaofeibao when(io.toRenameAllFire){ 368*0a7d1d5cSxiaofeibao u := Mux(renameIn(i).valid, 369*0a7d1d5cSxiaofeibao Mux(fuTypeOH(i).asUInt.orR, 370*0a7d1d5cSxiaofeibao Mux1H(fuTypeOH(i), minIQSelAll)(Mux1H(fuTypeOH(i), popFuTypeOH(i))), 371*0a7d1d5cSxiaofeibao Mux1H(fuTypeOHSingle(i), uopSelIQSingle)), 372*0a7d1d5cSxiaofeibao 0.U.asTypeOf(u) 373*0a7d1d5cSxiaofeibao ) 374*0a7d1d5cSxiaofeibao }.elsewhen(io.fromRename(i).fire){ 375*0a7d1d5cSxiaofeibao u := 0.U.asTypeOf(u) 376*0a7d1d5cSxiaofeibao } 377*0a7d1d5cSxiaofeibao }} 378*0a7d1d5cSxiaofeibao val uopSelIQMatrix = Wire(Vec(renameWidth, Vec(issueQueueNum, UInt(renameWidth.U.getWidth.W)))) 379*0a7d1d5cSxiaofeibao uopSelIQMatrix.zipWithIndex.map{ case (u, i) => { 380*0a7d1d5cSxiaofeibao u.zipWithIndex.map{ case (uu, j) => { 381*0a7d1d5cSxiaofeibao uu := PopCount(uopSelIQ.take(i+1).map(x => x.zipWithIndex.filter(_._2 == j).map(_._1)).flatten) 382*0a7d1d5cSxiaofeibao }} 383*0a7d1d5cSxiaofeibao }} 384*0a7d1d5cSxiaofeibao val IQSelUop = Wire(Vec(IQEnqSum, ValidIO(new DynInst))) 385*0a7d1d5cSxiaofeibao val uopBlockByIQ = Wire(Vec(renameWidth, Bool())) 386*0a7d1d5cSxiaofeibao val allowDispatch = Wire(Vec(renameWidth, Bool())) 387*0a7d1d5cSxiaofeibao val thisCanActualOut = Wire(Vec(renameWidth, Bool())) 388*0a7d1d5cSxiaofeibao val lsqCanAccept = Wire(Bool()) 389*0a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth){ 390*0a7d1d5cSxiaofeibao // update valid logic 391*0a7d1d5cSxiaofeibao fromRenameUpdate(i).valid := fromRename(i).valid && allowDispatch(i) && !uopBlockByIQ(i) && thisCanActualOut(i) && lsqCanAccept && !fromRename(i).bits.eliminatedMove 392*0a7d1d5cSxiaofeibao fromRename(i).ready := allowDispatch(i) && !uopBlockByIQ(i) && thisCanActualOut(i) && lsqCanAccept 393*0a7d1d5cSxiaofeibao } 394*0a7d1d5cSxiaofeibao var temp = 0 395*0a7d1d5cSxiaofeibao allIssueParams.zipWithIndex.map{ case(issue, iqidx) => { 396*0a7d1d5cSxiaofeibao for (i <- 0 until issue.numEnq){ 397*0a7d1d5cSxiaofeibao val oh = Wire(Vec(renameWidth, Bool())).suggestName(s"oh_IQSelUop_$temp") 398*0a7d1d5cSxiaofeibao oh := uopSelIQMatrix.map(_(iqidx)).map(_ === (i+1).U) 399*0a7d1d5cSxiaofeibao IQSelUop(temp) := PriorityMux(oh, fromRenameUpdate) 400*0a7d1d5cSxiaofeibao // there only assign valid not use PriorityMuxDefalut for better timing 401*0a7d1d5cSxiaofeibao IQSelUop(temp).valid := PriorityMuxDefault(oh.zip(fromRenameUpdate.map(_.valid)), false.B) 402*0a7d1d5cSxiaofeibao val allFuThisIQ = issue.exuBlockParams.map(_.fuConfigs).flatten.toSet.toSeq 403*0a7d1d5cSxiaofeibao val hasStaFu = !allFuThisIQ.filter(_.name == "sta").isEmpty 404*0a7d1d5cSxiaofeibao for (j <- 0 until numRegSrc){ 405*0a7d1d5cSxiaofeibao val maskForStd = hasStaFu && (j == 1) 406*0a7d1d5cSxiaofeibao val thisSrcHasInt = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) IntRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 407*0a7d1d5cSxiaofeibao val thisSrcHasFp = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) FpRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 408*0a7d1d5cSxiaofeibao val thisSrcHasVec = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) VecRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 409*0a7d1d5cSxiaofeibao val thisSrcHasV0 = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) V0RegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 410*0a7d1d5cSxiaofeibao val thisSrcHasVl = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) VlRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 411*0a7d1d5cSxiaofeibao val selSrcState = Seq(thisSrcHasInt || maskForStd, thisSrcHasFp || maskForStd, thisSrcHasVec, thisSrcHasV0, thisSrcHasVl) 412*0a7d1d5cSxiaofeibao IQSelUop(temp).bits.srcState(j) := PriorityMux(oh, allSrcState)(j).zip(selSrcState).filter(_._2 == true).map(_._1).foldLeft(false.B)(_ || _).asUInt 413*0a7d1d5cSxiaofeibao } 414*0a7d1d5cSxiaofeibao temp = temp + 1 415*0a7d1d5cSxiaofeibao if (backendParams.debugEn){ 416*0a7d1d5cSxiaofeibao dontTouch(oh) 417*0a7d1d5cSxiaofeibao } 418*0a7d1d5cSxiaofeibao } 419*0a7d1d5cSxiaofeibao }} 420*0a7d1d5cSxiaofeibao temp = 0 421*0a7d1d5cSxiaofeibao val uopBlockMatrix = Wire(Vec(renameWidth, Vec(issueQueueNum, Bool()))) 422*0a7d1d5cSxiaofeibao val uopBlockMatrixForAssign = allIssueParams.zipWithIndex.map { case (issue, iqidx) => { 423*0a7d1d5cSxiaofeibao val result = uopSelIQMatrix.map(_(iqidx)).map(x => Mux(io.toIssueQueues(temp).ready, x > issue.numEnq.U, x.orR)) 424*0a7d1d5cSxiaofeibao temp = temp + issue.numEnq 425*0a7d1d5cSxiaofeibao result 426*0a7d1d5cSxiaofeibao }}.transpose 427*0a7d1d5cSxiaofeibao uopBlockMatrix.zip(uopBlockMatrixForAssign).map(x => x._1 := VecInit(x._2)) 428*0a7d1d5cSxiaofeibao uopBlockByIQ := uopBlockMatrix.map(_.reduce(_ || _)) 429*0a7d1d5cSxiaofeibao io.toIssueQueues.zip(IQSelUop).map(x => { 430*0a7d1d5cSxiaofeibao x._1.valid := x._2.valid 431*0a7d1d5cSxiaofeibao x._1.bits := x._2.bits 432*0a7d1d5cSxiaofeibao }) 433*0a7d1d5cSxiaofeibao if (backendParams.debugEn){ 434*0a7d1d5cSxiaofeibao dontTouch(uopSelIQMatrix) 435*0a7d1d5cSxiaofeibao dontTouch(IQSelUop) 436*0a7d1d5cSxiaofeibao dontTouch(fromRenameUpdate) 437*0a7d1d5cSxiaofeibao dontTouch(uopBlockByIQ) 438*0a7d1d5cSxiaofeibao dontTouch(allowDispatch) 439*0a7d1d5cSxiaofeibao dontTouch(thisCanActualOut) 440*0a7d1d5cSxiaofeibao dontTouch(popFuTypeOH) 441*0a7d1d5cSxiaofeibao dontTouch(fuTypeOH) 442*0a7d1d5cSxiaofeibao dontTouch(fuTypeOHSingle) 443*0a7d1d5cSxiaofeibao dontTouch(minIQSelAll) 444*0a7d1d5cSxiaofeibao } 445*0a7d1d5cSxiaofeibao /////////////////////////////////////////////////////////// 446*0a7d1d5cSxiaofeibao 447*0a7d1d5cSxiaofeibao val lsqEnqCtrl = Module(new LsqEnqCtrl) 448*0a7d1d5cSxiaofeibao 449*0a7d1d5cSxiaofeibao // TODO: check lsqEnqCtrl redirect logic 450*0a7d1d5cSxiaofeibao // here is RegNext because dispatch2iq use s2_s4_redirect, newDispatch use s1_s3_redirect 451*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.redirect := RegNext(io.redirect) 452*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.lcommit := io.fromMem.lcommit 453*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.scommit := io.fromMem.scommit 454*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.lqCancelCnt := io.fromMem.lqCancelCnt 455*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.sqCancelCnt := io.fromMem.sqCancelCnt 456*0a7d1d5cSxiaofeibao lsqEnqCtrl.io.enq.iqAccept := io.fromRename.map(x => !x.valid || x.fire) 457*0a7d1d5cSxiaofeibao io.toMem.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 458*0a7d1d5cSxiaofeibao 459*0a7d1d5cSxiaofeibao private val enqLsqIO = lsqEnqCtrl.io.enq 460*0a7d1d5cSxiaofeibao private val lqFreeCount = lsqEnqCtrl.io.lqFreeCount 461*0a7d1d5cSxiaofeibao private val sqFreeCount = lsqEnqCtrl.io.sqFreeCount 462*0a7d1d5cSxiaofeibao 463*0a7d1d5cSxiaofeibao private val numLoadDeq = LSQLdEnqWidth 464*0a7d1d5cSxiaofeibao private val numStoreAMODeq = LSQStEnqWidth 465*0a7d1d5cSxiaofeibao private val numVLoadDeq = LoadPipelineWidth 466*0a7d1d5cSxiaofeibao private val numDeq = enqLsqIO.req.size 467*0a7d1d5cSxiaofeibao lsqCanAccept := enqLsqIO.canAccept 468*0a7d1d5cSxiaofeibao 469*0a7d1d5cSxiaofeibao private val isLoadVec = VecInit(fromRename.map(x => x.valid && FuType.isLoad(x.bits.fuType))) 470*0a7d1d5cSxiaofeibao private val isStoreVec = VecInit(fromRename.map(x => x.valid && FuType.isStore(x.bits.fuType))) 471*0a7d1d5cSxiaofeibao private val isAMOVec = fromRename.map(x => x.valid && FuType.isAMO(x.bits.fuType)) 472*0a7d1d5cSxiaofeibao private val isStoreAMOVec = fromRename.map(x => x.valid && (FuType.isStore(x.bits.fuType) || FuType.isAMO(x.bits.fuType))) 473*0a7d1d5cSxiaofeibao private val isVLoadVec = VecInit(fromRename.map(x => x.valid && FuType.isVLoad(x.bits.fuType))) 474*0a7d1d5cSxiaofeibao private val isVStoreVec = VecInit(fromRename.map(x => x.valid && FuType.isVStore(x.bits.fuType))) 475*0a7d1d5cSxiaofeibao 476*0a7d1d5cSxiaofeibao private val loadCntVec = VecInit(isLoadVec.indices.map(x => PopCount(isLoadVec.slice(0, x + 1)))) 477*0a7d1d5cSxiaofeibao private val storeAMOCntVec = VecInit(isStoreAMOVec.indices.map(x => PopCount(isStoreAMOVec.slice(0, x + 1)))) 478*0a7d1d5cSxiaofeibao private val vloadCntVec = VecInit(isVLoadVec.indices.map(x => PopCount(isVLoadVec.slice(0, x + 1)))) 479*0a7d1d5cSxiaofeibao 480*0a7d1d5cSxiaofeibao private val s0_enqLsq_resp = Wire(enqLsqIO.resp.cloneType) 481*0a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 482*0a7d1d5cSxiaofeibao // update lqIdx sqIdx 483*0a7d1d5cSxiaofeibao fromRenameUpdate(i).bits.lqIdx := s0_enqLsq_resp(i).lqIdx 484*0a7d1d5cSxiaofeibao fromRenameUpdate(i).bits.sqIdx := s0_enqLsq_resp(i).sqIdx 485*0a7d1d5cSxiaofeibao } 486*0a7d1d5cSxiaofeibao 487*0a7d1d5cSxiaofeibao val loadBlockVec = VecInit(loadCntVec.map(_ > numLoadDeq.U)) 488*0a7d1d5cSxiaofeibao val storeAMOBlockVec = VecInit(storeAMOCntVec.map(_ > numStoreAMODeq.U)) 489*0a7d1d5cSxiaofeibao val vloadBlockVec = VecInit(vloadCntVec.map(_ > numVLoadDeq.U)) 490*0a7d1d5cSxiaofeibao val lsStructBlockVec = VecInit((loadBlockVec.zip(storeAMOBlockVec)).zip(vloadBlockVec).map(x => x._1._1 || x._1._2 || x._2)) 491*0a7d1d5cSxiaofeibao if (backendParams.debugEn) { 492*0a7d1d5cSxiaofeibao dontTouch(loadBlockVec) 493*0a7d1d5cSxiaofeibao dontTouch(storeAMOBlockVec) 494*0a7d1d5cSxiaofeibao dontTouch(lsStructBlockVec) 495*0a7d1d5cSxiaofeibao dontTouch(vloadBlockVec) 496*0a7d1d5cSxiaofeibao dontTouch(isLoadVec) 497*0a7d1d5cSxiaofeibao dontTouch(isVLoadVec) 498*0a7d1d5cSxiaofeibao dontTouch(loadCntVec) 499*0a7d1d5cSxiaofeibao } 500*0a7d1d5cSxiaofeibao 501*0a7d1d5cSxiaofeibao private val uop = fromRename.map(_.bits) 502*0a7d1d5cSxiaofeibao private val fuType = uop.map(_.fuType) 503*0a7d1d5cSxiaofeibao private val fuOpType = uop.map(_.fuOpType) 504*0a7d1d5cSxiaofeibao private val vtype = uop.map(_.vpu.vtype) 505*0a7d1d5cSxiaofeibao private val sew = vtype.map(_.vsew) 506*0a7d1d5cSxiaofeibao private val lmul = vtype.map(_.vlmul) 507*0a7d1d5cSxiaofeibao private val eew = uop.map(_.vpu.veew) 508*0a7d1d5cSxiaofeibao private val mop = fuOpType.map(fuOpTypeItem => LSUOpType.getVecLSMop(fuOpTypeItem)) 509*0a7d1d5cSxiaofeibao private val nf = fuOpType.zip(uop.map(_.vpu.nf)).map { case (fuOpTypeItem, nfItem) => Mux(LSUOpType.isWhole(fuOpTypeItem), 0.U, nfItem) } 510*0a7d1d5cSxiaofeibao private val emul = fuOpType.zipWithIndex.map { case (fuOpTypeItem, index) => 511*0a7d1d5cSxiaofeibao Mux( 512*0a7d1d5cSxiaofeibao LSUOpType.isWhole(fuOpTypeItem), 513*0a7d1d5cSxiaofeibao GenUSWholeEmul(nf(index)), 514*0a7d1d5cSxiaofeibao Mux( 515*0a7d1d5cSxiaofeibao LSUOpType.isMasked(fuOpTypeItem), 516*0a7d1d5cSxiaofeibao 0.U(mulBits.W), 517*0a7d1d5cSxiaofeibao EewLog2(eew(index)) - sew(index) + lmul(index) 518*0a7d1d5cSxiaofeibao ) 519*0a7d1d5cSxiaofeibao ) 520*0a7d1d5cSxiaofeibao } 521*0a7d1d5cSxiaofeibao 522*0a7d1d5cSxiaofeibao private val isVlsType = fuType.map(fuTypeItem => FuType.isVls(fuTypeItem)).zip(fromRename.map(_.valid)).map(x => x._1 && x._2) 523*0a7d1d5cSxiaofeibao private val isSegment = fuType.map(fuTypeItem => FuType.isVsegls(fuTypeItem)).zip(fromRename.map(_.valid)).map(x => x._1 && x._2) 524*0a7d1d5cSxiaofeibao // TODO 525*0a7d1d5cSxiaofeibao private val isUnitStride = fuOpType.map(fuOpTypeItem => LSUOpType.isAllUS(fuOpTypeItem)) 526*0a7d1d5cSxiaofeibao private val isVecUnitType = isVlsType.zip(isUnitStride).map { case (isVlsTypeItme, isUnitStrideItem) => 527*0a7d1d5cSxiaofeibao isVlsTypeItme && isUnitStrideItem 528*0a7d1d5cSxiaofeibao } 529*0a7d1d5cSxiaofeibao private val isfofFixVlUop = uop.map { x => x.vpu.isVleff && x.lastUop } 530*0a7d1d5cSxiaofeibao private val instType = isSegment.zip(mop).map { case (isSegementItem, mopItem) => Cat(isSegementItem, mopItem) } 531*0a7d1d5cSxiaofeibao // There is no way to calculate the 'flow' for 'unit-stride' exactly: 532*0a7d1d5cSxiaofeibao // Whether 'unit-stride' needs to be split can only be known after obtaining the address. 533*0a7d1d5cSxiaofeibao // For scalar instructions, this is not handled here, and different assignments are done later according to the situation. 534*0a7d1d5cSxiaofeibao private val numLsElem = VecInit(uop.map(_.numLsElem)) 535*0a7d1d5cSxiaofeibao 536*0a7d1d5cSxiaofeibao // The maximum 'numLsElem' number that can be emitted per port is: 537*0a7d1d5cSxiaofeibao // 16 2 2 2 2 2. 538*0a7d1d5cSxiaofeibao // The 'allowDispatch' calculations are done conservatively for timing purposes: 539*0a7d1d5cSxiaofeibao // The Flow of scalar instructions is considered 1, 540*0a7d1d5cSxiaofeibao // The flow of vector 'unit-stride' instructions is considered 2, and the flow of other vector instructions is considered 16. 541*0a7d1d5cSxiaofeibao private val conserveFlows = isVlsType.zipWithIndex.map { case (isVlsTyepItem, index) => 542*0a7d1d5cSxiaofeibao Mux( 543*0a7d1d5cSxiaofeibao isVlsTyepItem, 544*0a7d1d5cSxiaofeibao if (index == 0) Mux(isUnitStride(index), VecMemUnitStrideMaxFlowNum.U, 16.U) else VecMemUnitStrideMaxFlowNum.U, 545*0a7d1d5cSxiaofeibao 1.U 546*0a7d1d5cSxiaofeibao ) 547*0a7d1d5cSxiaofeibao } 548*0a7d1d5cSxiaofeibao 549*0a7d1d5cSxiaofeibao // A conservative allocation strategy is adopted here. 550*0a7d1d5cSxiaofeibao // Vector 'unit-stride' instructions and scalar instructions can be issued from all six ports, 551*0a7d1d5cSxiaofeibao // while other vector instructions can only be issued from the first port 552*0a7d1d5cSxiaofeibao // if is segment instruction, need disptch it to Vldst_RS0, so, except port 0, stall other. 553*0a7d1d5cSxiaofeibao // The allocation needs to meet a few conditions: 554*0a7d1d5cSxiaofeibao // 1) The lsq has enough entris. 555*0a7d1d5cSxiaofeibao // 2) The number of flows accumulated does not exceed VecMemDispatchMaxNumber. 556*0a7d1d5cSxiaofeibao // 3) Vector instructions other than 'unit-stride' can only be issued on the first port. 557*0a7d1d5cSxiaofeibao 558*0a7d1d5cSxiaofeibao 559*0a7d1d5cSxiaofeibao for (index <- allowDispatch.indices) { 560*0a7d1d5cSxiaofeibao val flowTotal = Wire(UInt(log2Up(VirtualLoadQueueMaxStoreQueueSize + 1).W)) 561*0a7d1d5cSxiaofeibao flowTotal := conserveFlows.take(index + 1).reduce(_ +& _) 562*0a7d1d5cSxiaofeibao if (index == 0) { 563*0a7d1d5cSxiaofeibao when(isStoreVec(index) || isVStoreVec(index)) { 564*0a7d1d5cSxiaofeibao allowDispatch(index) := sqFreeCount > flowTotal 565*0a7d1d5cSxiaofeibao }.elsewhen(isLoadVec(index) || isVLoadVec(index)) { 566*0a7d1d5cSxiaofeibao allowDispatch(index) := lqFreeCount > flowTotal 567*0a7d1d5cSxiaofeibao }.elsewhen(isAMOVec(index)) { 568*0a7d1d5cSxiaofeibao allowDispatch(index) := true.B 569*0a7d1d5cSxiaofeibao }.otherwise { 570*0a7d1d5cSxiaofeibao allowDispatch(index) := true.B 571*0a7d1d5cSxiaofeibao } 572*0a7d1d5cSxiaofeibao } 573*0a7d1d5cSxiaofeibao else { 574*0a7d1d5cSxiaofeibao when(isStoreVec(index) || isVStoreVec(index)) { 575*0a7d1d5cSxiaofeibao allowDispatch(index) := (sqFreeCount > flowTotal) && (isVecUnitType(index) || !isVlsType(index)) && allowDispatch(index - 1) 576*0a7d1d5cSxiaofeibao }.elsewhen(isLoadVec(index) || isVLoadVec(index)) { 577*0a7d1d5cSxiaofeibao allowDispatch(index) := (lqFreeCount > flowTotal) && (isVecUnitType(index) || !isVlsType(index)) && allowDispatch(index - 1) 578*0a7d1d5cSxiaofeibao }.elsewhen(isAMOVec(index)) { 579*0a7d1d5cSxiaofeibao allowDispatch(index) := allowDispatch(index - 1) 580*0a7d1d5cSxiaofeibao }.otherwise { 581*0a7d1d5cSxiaofeibao allowDispatch(index) := allowDispatch(index - 1) 582*0a7d1d5cSxiaofeibao } 583*0a7d1d5cSxiaofeibao } 584*0a7d1d5cSxiaofeibao } 585*0a7d1d5cSxiaofeibao 586*0a7d1d5cSxiaofeibao 587*0a7d1d5cSxiaofeibao // enqLsq io 588*0a7d1d5cSxiaofeibao require(enqLsqIO.req.size == enqLsqIO.resp.size) 589*0a7d1d5cSxiaofeibao for (i <- enqLsqIO.req.indices) { 590*0a7d1d5cSxiaofeibao when(!io.fromRename(i).fire) { 591*0a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 0.U 592*0a7d1d5cSxiaofeibao }.elsewhen(isStoreVec(i) || isVStoreVec(i)) { 593*0a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 2.U // store | vstore 594*0a7d1d5cSxiaofeibao }.elsewhen(isLoadVec(i) || isVLoadVec(i)){ 595*0a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 1.U // load | vload 596*0a7d1d5cSxiaofeibao }.otherwise { 597*0a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 0.U 598*0a7d1d5cSxiaofeibao } 599*0a7d1d5cSxiaofeibao enqLsqIO.req(i).valid := io.fromRename(i).fire && !isAMOVec(i) && !isSegment(i) && !isfofFixVlUop(i) 600*0a7d1d5cSxiaofeibao enqLsqIO.req(i).bits := io.fromRename(i).bits 601*0a7d1d5cSxiaofeibao 602*0a7d1d5cSxiaofeibao // This is to make it easier to calculate in LSQ. 603*0a7d1d5cSxiaofeibao // Both scalar instructions and vector instructions with FLOW equal to 1 have a NUM value of 1.” 604*0a7d1d5cSxiaofeibao // But, the 'numLsElem' that is not a vector is set to 0 when passed to IQ 605*0a7d1d5cSxiaofeibao enqLsqIO.req(i).bits.numLsElem := Mux(isVlsType(i), numLsElem(i), 1.U) 606*0a7d1d5cSxiaofeibao s0_enqLsq_resp(i) := enqLsqIO.resp(i) 607*0a7d1d5cSxiaofeibao } 608*0a7d1d5cSxiaofeibao 609*0a7d1d5cSxiaofeibao 610*0a7d1d5cSxiaofeibao 611*0a7d1d5cSxiaofeibao 612*0a7d1d5cSxiaofeibao 613*0a7d1d5cSxiaofeibao 614*0a7d1d5cSxiaofeibao 615*0a7d1d5cSxiaofeibao 616*0a7d1d5cSxiaofeibao 617*0a7d1d5cSxiaofeibao 618*0a7d1d5cSxiaofeibao 619*0a7d1d5cSxiaofeibao 620*0a7d1d5cSxiaofeibao val isFp = VecInit(fromRename.map(req => FuType.isFArith(req.bits.fuType))) 621*0a7d1d5cSxiaofeibao val isVec = VecInit(fromRename.map(req => FuType.isVArith (req.bits.fuType) || 622*0a7d1d5cSxiaofeibao FuType.isVsetRvfWvf(req.bits.fuType))) 623*0a7d1d5cSxiaofeibao val isMem = VecInit(fromRename.map(req => FuType.isMem(req.bits.fuType) || 624*0a7d1d5cSxiaofeibao FuType.isVls (req.bits.fuType))) 625*0a7d1d5cSxiaofeibao val isLs = VecInit(fromRename.map(req => FuType.isLoadStore(req.bits.fuType))) 626*0a7d1d5cSxiaofeibao val isVls = VecInit(fromRename.map(req => FuType.isVls (req.bits.fuType))) 627*0a7d1d5cSxiaofeibao val isStore = VecInit(fromRename.map(req => FuType.isStore(req.bits.fuType))) 628*0a7d1d5cSxiaofeibao val isVStore = VecInit(fromRename.map(req => FuType.isVStore(req.bits.fuType))) 629*0a7d1d5cSxiaofeibao val isAMO = VecInit(fromRename.map(req => FuType.isAMO(req.bits.fuType))) 630*0a7d1d5cSxiaofeibao val isBlockBackward = VecInit(fromRename.map(x => x.valid && x.bits.blockBackward)) 631*0a7d1d5cSxiaofeibao val isWaitForward = VecInit(fromRename.map(x => x.valid && x.bits.waitForward)) 632*0a7d1d5cSxiaofeibao 633*0a7d1d5cSxiaofeibao // Singlestep should only commit one machine instruction after dret, and then hart enter debugMode according to singlestep exception. 634*0a7d1d5cSxiaofeibao val s_holdRobidx :: s_updateRobidx :: Nil = Enum(2) 635*0a7d1d5cSxiaofeibao val singleStepState = RegInit(s_updateRobidx) 636*0a7d1d5cSxiaofeibao 637*0a7d1d5cSxiaofeibao val robidxStepNext = WireInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 638*0a7d1d5cSxiaofeibao val robidxStepReg = RegInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 639*0a7d1d5cSxiaofeibao val robidxCanCommitStepping = WireInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 640*0a7d1d5cSxiaofeibao 641*0a7d1d5cSxiaofeibao when(!io.singleStep) { 642*0a7d1d5cSxiaofeibao singleStepState := s_updateRobidx 643*0a7d1d5cSxiaofeibao }.elsewhen(io.singleStep && fromRename(0).fire && io.enqRob.req(0).valid) { 644*0a7d1d5cSxiaofeibao singleStepState := s_holdRobidx 645*0a7d1d5cSxiaofeibao robidxStepNext := fromRename(0).bits.robIdx 646*0a7d1d5cSxiaofeibao } 647*0a7d1d5cSxiaofeibao 648*0a7d1d5cSxiaofeibao when(singleStepState === s_updateRobidx) { 649*0a7d1d5cSxiaofeibao robidxStepReg := robidxStepNext 650*0a7d1d5cSxiaofeibao robidxCanCommitStepping := robidxStepNext 651*0a7d1d5cSxiaofeibao }.elsewhen(singleStepState === s_holdRobidx) { 652*0a7d1d5cSxiaofeibao robidxStepReg := robidxStepReg 653*0a7d1d5cSxiaofeibao robidxCanCommitStepping := robidxStepReg 654*0a7d1d5cSxiaofeibao } 655*0a7d1d5cSxiaofeibao 656*0a7d1d5cSxiaofeibao val updatedUop = Wire(Vec(RenameWidth, new DynInst)) 657*0a7d1d5cSxiaofeibao val checkpoint_id = RegInit(0.U(64.W)) 658*0a7d1d5cSxiaofeibao checkpoint_id := checkpoint_id + PopCount((0 until RenameWidth).map(i => 659*0a7d1d5cSxiaofeibao fromRename(i).fire 660*0a7d1d5cSxiaofeibao )) 661*0a7d1d5cSxiaofeibao 662*0a7d1d5cSxiaofeibao 663*0a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 664*0a7d1d5cSxiaofeibao 665*0a7d1d5cSxiaofeibao updatedUop(i) := fromRename(i).bits 666*0a7d1d5cSxiaofeibao updatedUop(i).debugInfo.eliminatedMove := fromRename(i).bits.eliminatedMove 667*0a7d1d5cSxiaofeibao // For the LUI instruction: psrc(0) is from register file and should always be zero. 668*0a7d1d5cSxiaofeibao when (fromRename(i).bits.isLUI) { 669*0a7d1d5cSxiaofeibao updatedUop(i).psrc(0) := 0.U 670*0a7d1d5cSxiaofeibao } 671*0a7d1d5cSxiaofeibao //TODO: vec ls mdp 672*0a7d1d5cSxiaofeibao io.lfst.req(i).valid := fromRename(i).fire && updatedUop(i).storeSetHit 673*0a7d1d5cSxiaofeibao io.lfst.req(i).bits.isstore := isStore(i) 674*0a7d1d5cSxiaofeibao io.lfst.req(i).bits.ssid := updatedUop(i).ssid 675*0a7d1d5cSxiaofeibao io.lfst.req(i).bits.robIdx := updatedUop(i).robIdx // speculatively assigned in rename 676*0a7d1d5cSxiaofeibao 677*0a7d1d5cSxiaofeibao // override load delay ctrl signal with store set result 678*0a7d1d5cSxiaofeibao if(StoreSetEnable) { 679*0a7d1d5cSxiaofeibao updatedUop(i).loadWaitBit := io.lfst.resp(i).bits.shouldWait 680*0a7d1d5cSxiaofeibao updatedUop(i).waitForRobIdx := io.lfst.resp(i).bits.robIdx 681*0a7d1d5cSxiaofeibao } else { 682*0a7d1d5cSxiaofeibao updatedUop(i).loadWaitBit := isLs(i) && !isStore(i) && fromRename(i).bits.loadWaitBit 683*0a7d1d5cSxiaofeibao } 684*0a7d1d5cSxiaofeibao // // update singleStep, singleStep exception only enable in next machine instruction. 685*0a7d1d5cSxiaofeibao updatedUop(i).singleStep := io.singleStep && (fromRename(i).bits.robIdx =/= robidxCanCommitStepping) 686*0a7d1d5cSxiaofeibao when (fromRename(i).fire) { 687*0a7d1d5cSxiaofeibao XSDebug(TriggerAction.isDmode(updatedUop(i).trigger) || updatedUop(i).exceptionVec(breakPoint), s"Debug Mode: inst ${i} has frontend trigger exception\n") 688*0a7d1d5cSxiaofeibao XSDebug(updatedUop(i).singleStep, s"Debug Mode: inst ${i} has single step exception\n") 689*0a7d1d5cSxiaofeibao } 690*0a7d1d5cSxiaofeibao if (env.EnableDifftest) { 691*0a7d1d5cSxiaofeibao // debug runahead hint 692*0a7d1d5cSxiaofeibao val debug_runahead_checkpoint_id = Wire(checkpoint_id.cloneType) 693*0a7d1d5cSxiaofeibao if(i == 0){ 694*0a7d1d5cSxiaofeibao debug_runahead_checkpoint_id := checkpoint_id 695*0a7d1d5cSxiaofeibao } else { 696*0a7d1d5cSxiaofeibao debug_runahead_checkpoint_id := checkpoint_id + PopCount((0 until i).map(i => 697*0a7d1d5cSxiaofeibao fromRename(i).fire 698*0a7d1d5cSxiaofeibao )) 699*0a7d1d5cSxiaofeibao } 700*0a7d1d5cSxiaofeibao } 701*0a7d1d5cSxiaofeibao } 702*0a7d1d5cSxiaofeibao 703*0a7d1d5cSxiaofeibao // store set perf count 704*0a7d1d5cSxiaofeibao XSPerfAccumulate("waittable_load_wait", PopCount((0 until RenameWidth).map(i => 705*0a7d1d5cSxiaofeibao fromRename(i).fire && fromRename(i).bits.loadWaitBit && !isStore(i) && isLs(i) 706*0a7d1d5cSxiaofeibao ))) 707*0a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_load_wait", PopCount((0 until RenameWidth).map(i => 708*0a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && !isStore(i) && isLs(i) 709*0a7d1d5cSxiaofeibao ))) 710*0a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_load_strict_wait", PopCount((0 until RenameWidth).map(i => 711*0a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && updatedUop(i).loadWaitStrict && !isStore(i) && isLs(i) 712*0a7d1d5cSxiaofeibao ))) 713*0a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_store_wait", PopCount((0 until RenameWidth).map(i => 714*0a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && isStore(i) 715*0a7d1d5cSxiaofeibao ))) 716*0a7d1d5cSxiaofeibao 717*0a7d1d5cSxiaofeibao val allResourceReady = io.enqRob.canAccept 718*0a7d1d5cSxiaofeibao 719*0a7d1d5cSxiaofeibao // Instructions should enter dispatch queues in order. 720*0a7d1d5cSxiaofeibao // blockedByWaitForward: this instruction is blocked by itself (based on waitForward) 721*0a7d1d5cSxiaofeibao // nextCanOut: next instructions can out (based on blockBackward) 722*0a7d1d5cSxiaofeibao // notBlockedByPrevious: previous instructions can enqueue 723*0a7d1d5cSxiaofeibao val hasException = VecInit(fromRename.zip(updatedUop).map { 724*0a7d1d5cSxiaofeibao case (fromRename: DecoupledIO[DynInst], uop: DynInst) => 725*0a7d1d5cSxiaofeibao fromRename.bits.hasException || uop.singleStep 726*0a7d1d5cSxiaofeibao }) 727*0a7d1d5cSxiaofeibao 728*0a7d1d5cSxiaofeibao private val blockedByWaitForward = Wire(Vec(RenameWidth, Bool())) 729*0a7d1d5cSxiaofeibao blockedByWaitForward(0) := !io.enqRob.isEmpty && isWaitForward(0) 730*0a7d1d5cSxiaofeibao for (i <- 1 until RenameWidth) { 731*0a7d1d5cSxiaofeibao blockedByWaitForward(i) := blockedByWaitForward(i - 1) || (!io.enqRob.isEmpty || Cat(fromRename.take(i).map(_.valid)).orR) && isWaitForward(i) 732*0a7d1d5cSxiaofeibao } 733*0a7d1d5cSxiaofeibao if(backendParams.debugEn){ 734*0a7d1d5cSxiaofeibao dontTouch(blockedByWaitForward) 735*0a7d1d5cSxiaofeibao } 736*0a7d1d5cSxiaofeibao 737*0a7d1d5cSxiaofeibao // Only the uop with block backward flag will block the next uop 738*0a7d1d5cSxiaofeibao val nextCanOut = VecInit((0 until RenameWidth).map(i => 739*0a7d1d5cSxiaofeibao !isBlockBackward(i) 740*0a7d1d5cSxiaofeibao )) 741*0a7d1d5cSxiaofeibao val notBlockedByPrevious = VecInit((0 until RenameWidth).map(i => 742*0a7d1d5cSxiaofeibao if (i == 0) true.B 743*0a7d1d5cSxiaofeibao else Cat((0 until i).map(j => nextCanOut(j))).andR 744*0a7d1d5cSxiaofeibao )) 745*0a7d1d5cSxiaofeibao 746*0a7d1d5cSxiaofeibao // for noSpecExec: (robEmpty || !this.noSpecExec) && !previous.noSpecExec 747*0a7d1d5cSxiaofeibao // For blockBackward: 748*0a7d1d5cSxiaofeibao // this instruction can actually dequeue: 3 conditions 749*0a7d1d5cSxiaofeibao // (1) resources are ready 750*0a7d1d5cSxiaofeibao // (2) previous instructions are ready 751*0a7d1d5cSxiaofeibao thisCanActualOut := VecInit((0 until RenameWidth).map(i => !blockedByWaitForward(i) && notBlockedByPrevious(i) && io.enqRob.canAccept)) 752*0a7d1d5cSxiaofeibao val thisActualOut = (0 until RenameWidth).map(i => io.enqRob.req(i).valid && io.enqRob.canAccept) 753*0a7d1d5cSxiaofeibao val hasValidException = fromRename.zip(hasException).map(x => x._1.valid && x._2) 754*0a7d1d5cSxiaofeibao 755*0a7d1d5cSxiaofeibao // input for ROB, LSQ 756*0a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 757*0a7d1d5cSxiaofeibao // needAlloc no use, need deleted 758*0a7d1d5cSxiaofeibao io.enqRob.needAlloc(i) := fromRename(i).valid 759*0a7d1d5cSxiaofeibao io.enqRob.req(i).valid := fromRename(i).fire 760*0a7d1d5cSxiaofeibao io.enqRob.req(i).bits := updatedUop(i) 761*0a7d1d5cSxiaofeibao io.enqRob.req(i).bits.hasException := updatedUop(i).hasException || updatedUop(i).singleStep 762*0a7d1d5cSxiaofeibao io.enqRob.req(i).bits.numWB := Mux(updatedUop(i).singleStep, 0.U, updatedUop(i).numWB) 763*0a7d1d5cSxiaofeibao } 764*0a7d1d5cSxiaofeibao 765*0a7d1d5cSxiaofeibao val hasValidInstr = VecInit(fromRename.map(_.valid)).asUInt.orR 766*0a7d1d5cSxiaofeibao val hasSpecialInstr = Cat((0 until RenameWidth).map(i => isBlockBackward(i))).orR 767*0a7d1d5cSxiaofeibao 768*0a7d1d5cSxiaofeibao private val canAccept = !hasValidInstr || !hasSpecialInstr && io.enqRob.canAccept 769*0a7d1d5cSxiaofeibao 770*0a7d1d5cSxiaofeibao val isWaitForwardOrBlockBackward = isWaitForward.asUInt.orR || isBlockBackward.asUInt.orR 771*0a7d1d5cSxiaofeibao val renameFireCnt = PopCount(fromRename.map(_.fire)) 772*0a7d1d5cSxiaofeibao 773*0a7d1d5cSxiaofeibao val stall_rob = hasValidInstr && !io.enqRob.canAccept 774*0a7d1d5cSxiaofeibao val stall_int_dq = hasValidInstr && io.enqRob.canAccept 775*0a7d1d5cSxiaofeibao val stall_int_dq0 = hasValidInstr && io.enqRob.canAccept 776*0a7d1d5cSxiaofeibao val stall_int_dq1 = hasValidInstr && io.enqRob.canAccept 777*0a7d1d5cSxiaofeibao val stall_fp_dq = hasValidInstr && io.enqRob.canAccept 778*0a7d1d5cSxiaofeibao val stall_ls_dq = hasValidInstr && io.enqRob.canAccept 779*0a7d1d5cSxiaofeibao 780*0a7d1d5cSxiaofeibao XSPerfAccumulate("in_valid_count", PopCount(fromRename.map(_.valid))) 781*0a7d1d5cSxiaofeibao XSPerfAccumulate("in_fire_count", PopCount(fromRename.map(_.fire))) 782*0a7d1d5cSxiaofeibao XSPerfAccumulate("in_valid_not_ready_count", PopCount(fromRename.map(x => x.valid && !x.ready))) 783*0a7d1d5cSxiaofeibao XSPerfAccumulate("wait_cycle", !fromRename.head.valid && allResourceReady) 784*0a7d1d5cSxiaofeibao 785*0a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_rob", stall_rob) 786*0a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_int_dq0", stall_int_dq0) 787*0a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_int_dq1", stall_int_dq1) 788*0a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_fp_dq", stall_fp_dq) 789*0a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_ls_dq", stall_ls_dq) 790*0a7d1d5cSxiaofeibao 791*0a7d1d5cSxiaofeibao val notIssue = !io.debugTopDown.fromRob.robHeadLsIssue 792*0a7d1d5cSxiaofeibao val tlbReplay = io.debugTopDown.fromCore.fromMem.robHeadTlbReplay 793*0a7d1d5cSxiaofeibao val tlbMiss = io.debugTopDown.fromCore.fromMem.robHeadTlbMiss 794*0a7d1d5cSxiaofeibao val vioReplay = io.debugTopDown.fromCore.fromMem.robHeadLoadVio 795*0a7d1d5cSxiaofeibao val mshrReplay = io.debugTopDown.fromCore.fromMem.robHeadLoadMSHR 796*0a7d1d5cSxiaofeibao val l1Miss = io.debugTopDown.fromCore.fromMem.robHeadMissInDCache 797*0a7d1d5cSxiaofeibao val l2Miss = io.debugTopDown.fromCore.l2MissMatch 798*0a7d1d5cSxiaofeibao val l3Miss = io.debugTopDown.fromCore.l3MissMatch 799*0a7d1d5cSxiaofeibao 800*0a7d1d5cSxiaofeibao val ldReason = Mux(l3Miss, TopDownCounters.LoadMemStall.id.U, 801*0a7d1d5cSxiaofeibao Mux(l2Miss, TopDownCounters.LoadL3Stall.id.U, 802*0a7d1d5cSxiaofeibao Mux(l1Miss, TopDownCounters.LoadL2Stall.id.U, 803*0a7d1d5cSxiaofeibao Mux(notIssue, TopDownCounters.MemNotReadyStall.id.U, 804*0a7d1d5cSxiaofeibao Mux(tlbMiss, TopDownCounters.LoadTLBStall.id.U, 805*0a7d1d5cSxiaofeibao Mux(tlbReplay, TopDownCounters.LoadTLBStall.id.U, 806*0a7d1d5cSxiaofeibao Mux(mshrReplay, TopDownCounters.LoadMSHRReplayStall.id.U, 807*0a7d1d5cSxiaofeibao Mux(vioReplay, TopDownCounters.LoadVioReplayStall.id.U, 808*0a7d1d5cSxiaofeibao TopDownCounters.LoadL1Stall.id.U)))))))) 809*0a7d1d5cSxiaofeibao 810*0a7d1d5cSxiaofeibao val decodeReason = RegNextN(io.stallReason.reason, 2) 811*0a7d1d5cSxiaofeibao val renameReason = RegNext(io.stallReason.reason) 812*0a7d1d5cSxiaofeibao 813*0a7d1d5cSxiaofeibao val stallReason = Wire(chiselTypeOf(io.stallReason.reason)) 814*0a7d1d5cSxiaofeibao val firedVec = fromRename.map(_.fire) 815*0a7d1d5cSxiaofeibao io.stallReason.backReason.valid := !canAccept 816*0a7d1d5cSxiaofeibao io.stallReason.backReason.bits := TopDownCounters.OtherCoreStall.id.U 817*0a7d1d5cSxiaofeibao stallReason.zip(io.stallReason.reason).zip(firedVec).zipWithIndex.map { case (((update, in), fire), idx) => 818*0a7d1d5cSxiaofeibao val headIsInt = FuType.isInt(io.robHead.getDebugFuType) && io.robHeadNotReady 819*0a7d1d5cSxiaofeibao val headIsFp = FuType.isFArith(io.robHead.getDebugFuType) && io.robHeadNotReady 820*0a7d1d5cSxiaofeibao val headIsDiv = FuType.isDivSqrt(io.robHead.getDebugFuType) && io.robHeadNotReady 821*0a7d1d5cSxiaofeibao val headIsLd = io.robHead.getDebugFuType === FuType.ldu.U && io.robHeadNotReady || !io.lqCanAccept 822*0a7d1d5cSxiaofeibao val headIsSt = io.robHead.getDebugFuType === FuType.stu.U && io.robHeadNotReady || !io.sqCanAccept 823*0a7d1d5cSxiaofeibao val headIsAmo = io.robHead.getDebugFuType === FuType.mou.U && io.robHeadNotReady 824*0a7d1d5cSxiaofeibao val headIsLs = headIsLd || headIsSt 825*0a7d1d5cSxiaofeibao val robLsFull = io.robFull || !io.lqCanAccept || !io.sqCanAccept 826*0a7d1d5cSxiaofeibao 827*0a7d1d5cSxiaofeibao import TopDownCounters._ 828*0a7d1d5cSxiaofeibao update := MuxCase(OtherCoreStall.id.U, Seq( 829*0a7d1d5cSxiaofeibao // fire 830*0a7d1d5cSxiaofeibao (fire ) -> NoStall.id.U , 831*0a7d1d5cSxiaofeibao // dispatch not stall / core stall from decode or rename 832*0a7d1d5cSxiaofeibao (in =/= OtherCoreStall.id.U && in =/= NoStall.id.U ) -> in , 833*0a7d1d5cSxiaofeibao // rob stall 834*0a7d1d5cSxiaofeibao (headIsAmo ) -> AtomicStall.id.U , 835*0a7d1d5cSxiaofeibao (headIsSt ) -> StoreStall.id.U , 836*0a7d1d5cSxiaofeibao (headIsLd ) -> ldReason , 837*0a7d1d5cSxiaofeibao (headIsDiv ) -> DivStall.id.U , 838*0a7d1d5cSxiaofeibao (headIsInt ) -> IntNotReadyStall.id.U , 839*0a7d1d5cSxiaofeibao (headIsFp ) -> FPNotReadyStall.id.U , 840*0a7d1d5cSxiaofeibao (renameReason(idx) =/= NoStall.id.U ) -> renameReason(idx) , 841*0a7d1d5cSxiaofeibao (decodeReason(idx) =/= NoStall.id.U ) -> decodeReason(idx) , 842*0a7d1d5cSxiaofeibao )) 843*0a7d1d5cSxiaofeibao } 844*0a7d1d5cSxiaofeibao 845*0a7d1d5cSxiaofeibao TopDownCounters.values.foreach(ctr => XSPerfAccumulate(ctr.toString(), PopCount(stallReason.map(_ === ctr.id.U)))) 846*0a7d1d5cSxiaofeibao 847*0a7d1d5cSxiaofeibao val robTrueCommit = io.debugTopDown.fromRob.robTrueCommit 848*0a7d1d5cSxiaofeibao TopDownCounters.values.foreach(ctr => XSPerfRolling("td_"+ctr.toString(), PopCount(stallReason.map(_ === ctr.id.U)), 849*0a7d1d5cSxiaofeibao robTrueCommit, 1000, clock, reset)) 850*0a7d1d5cSxiaofeibao 851*0a7d1d5cSxiaofeibao XSPerfHistogram("slots_fire", PopCount(thisActualOut), true.B, 0, RenameWidth+1, 1) 852*0a7d1d5cSxiaofeibao // Explaination: when out(0) not fire, PopCount(valid) is not meaningfull 853*0a7d1d5cSxiaofeibao XSPerfHistogram("slots_valid_pure", PopCount(io.enqRob.req.map(_.valid)), thisActualOut(0), 0, RenameWidth+1, 1) 854*0a7d1d5cSxiaofeibao XSPerfHistogram("slots_valid_rough", PopCount(io.enqRob.req.map(_.valid)), true.B, 0, RenameWidth+1, 1) 855*0a7d1d5cSxiaofeibao 856*0a7d1d5cSxiaofeibao val perfEvents = Seq( 857*0a7d1d5cSxiaofeibao ("dispatch_in", PopCount(fromRename.map(_.valid && fromRename(0).ready)) ), 858*0a7d1d5cSxiaofeibao ("dispatch_empty", !hasValidInstr ), 859*0a7d1d5cSxiaofeibao ("dispatch_utili", PopCount(fromRename.map(_.valid)) ), 860*0a7d1d5cSxiaofeibao ("dispatch_waitinstr", PopCount(fromRename.map(!_.valid && canAccept)) ), 861*0a7d1d5cSxiaofeibao ("dispatch_stall_cycle_lsq", false.B ), 862*0a7d1d5cSxiaofeibao ("dispatch_stall_cycle_rob", stall_rob ), 863*0a7d1d5cSxiaofeibao ("dispatch_stall_cycle_int_dq", stall_int_dq ), 864*0a7d1d5cSxiaofeibao ("dispatch_stall_cycle_fp_dq", stall_fp_dq ), 865*0a7d1d5cSxiaofeibao ("dispatch_stall_cycle_ls_dq", stall_ls_dq ) 866*0a7d1d5cSxiaofeibao ) 867*0a7d1d5cSxiaofeibao generatePerfEvent() 868*0a7d1d5cSxiaofeibao} 869