10a7d1d5cSxiaofeibao/*************************************************************************************** 20a7d1d5cSxiaofeibao* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 30a7d1d5cSxiaofeibao* Copyright (c) 2020-2021 Peng Cheng Laboratory 40a7d1d5cSxiaofeibao* 50a7d1d5cSxiaofeibao* XiangShan is licensed under Mulan PSL v2. 60a7d1d5cSxiaofeibao* You can use this software according to the terms and conditions of the Mulan PSL v2. 70a7d1d5cSxiaofeibao* You may obtain a copy of Mulan PSL v2 at: 80a7d1d5cSxiaofeibao* http://license.coscl.org.cn/MulanPSL2 90a7d1d5cSxiaofeibao* 100a7d1d5cSxiaofeibao* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 110a7d1d5cSxiaofeibao* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 120a7d1d5cSxiaofeibao* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 130a7d1d5cSxiaofeibao* 140a7d1d5cSxiaofeibao* See the Mulan PSL v2 for more details. 150a7d1d5cSxiaofeibao***************************************************************************************/ 160a7d1d5cSxiaofeibao 170a7d1d5cSxiaofeibaopackage xiangshan.backend.dispatch 180a7d1d5cSxiaofeibao 190a7d1d5cSxiaofeibaoimport org.chipsalliance.cde.config.Parameters 200a7d1d5cSxiaofeibaoimport chisel3._ 210a7d1d5cSxiaofeibaoimport chisel3.util._ 22c590fb32Scz4eimport chisel3.util.experimental.decode._ 23c590fb32Scz4eimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 240a7d1d5cSxiaofeibaoimport utility._ 250a7d1d5cSxiaofeibaoimport xiangshan.ExceptionNO._ 260a7d1d5cSxiaofeibaoimport xiangshan._ 270a7d1d5cSxiaofeibaoimport xiangshan.backend.rob.{RobDispatchTopDownIO, RobEnqIO} 284e7f9e52Sxiaofeibaoimport xiangshan.backend.Bundles.{DecodedInst, DynInst, ExuVec, IssueQueueIQWakeUpBundle} 290a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.{FuConfig, FuType} 307edcfc93SZiyue Zhangimport xiangshan.backend.rename.{BusyTable, VlBusyTable} 310a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.{FuConfig, FuType} 320a7d1d5cSxiaofeibaoimport xiangshan.backend.rename.BusyTableReadIO 330a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.DataConfig._ 340a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.WbConfig._ 350a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.DataSource 360a7d1d5cSxiaofeibaoimport xiangshan.backend.datapath.WbConfig.VfWB 370a7d1d5cSxiaofeibaoimport xiangshan.backend.fu.FuType.FuTypeOrR 380a7d1d5cSxiaofeibaoimport xiangshan.backend.regcache.{RCTagTableReadPort, RegCacheTagTable} 39c590fb32Scz4eimport xiangshan.mem.MemCoreTopDownIO 40c590fb32Scz4eimport xiangshan.mem.mdp._ 41c590fb32Scz4eimport xiangshan.mem.{HasVLSUParameters, _} 420a7d1d5cSxiaofeibao 43914bbc86Sxiaofeibao-xjtuclass CoreDispatchTopDownIO extends Bundle { 44914bbc86Sxiaofeibao-xjtu val l2MissMatch = Input(Bool()) 45914bbc86Sxiaofeibao-xjtu val l3MissMatch = Input(Bool()) 46914bbc86Sxiaofeibao-xjtu val fromMem = Flipped(new MemCoreTopDownIO) 47914bbc86Sxiaofeibao-xjtu} 480a7d1d5cSxiaofeibao// TODO delete trigger message from frontend to iq 490a7d1d5cSxiaofeibaoclass NewDispatch(implicit p: Parameters) extends XSModule with HasPerfEvents with HasVLSUParameters { 500a7d1d5cSxiaofeibao // std IQ donot need dispatch, only copy sta IQ, but need sta IQ's ready && std IQ's ready 510a7d1d5cSxiaofeibao val allIssueParams = backendParams.allIssueParams.filter(_.StdCnt == 0) 520a7d1d5cSxiaofeibao val allExuParams = allIssueParams.map(_.exuBlockParams).flatten 530a7d1d5cSxiaofeibao val allFuConfigs = allExuParams.map(_.fuConfigs).flatten.toSet.toSeq 540a7d1d5cSxiaofeibao val sortedFuConfigs = allFuConfigs.sortBy(_.fuType.id) 550a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allExuParams.map(_.name)}") 560a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allFuConfigs.map(_.name)}") 570a7d1d5cSxiaofeibao println(s"[NewDispatch] ${allFuConfigs.map(_.fuType.id)}") 580a7d1d5cSxiaofeibao println(s"[NewDispatch] ${sortedFuConfigs.map(_.name)}") 590a7d1d5cSxiaofeibao println(s"[NewDispatch] ${sortedFuConfigs.map(_.fuType.id)}") 600a7d1d5cSxiaofeibao val fuConfigsInIssueParams = allIssueParams.map(_.allExuParams.map(_.fuConfigs).flatten.toSet.toSeq) 610a7d1d5cSxiaofeibao val fuMapIQIdx = sortedFuConfigs.map( fu => { 620a7d1d5cSxiaofeibao val fuInIQIdx = fuConfigsInIssueParams.zipWithIndex.filter { case (f, i) => f.contains(fu) }.map(_._2) 630a7d1d5cSxiaofeibao (fu -> fuInIQIdx) 640a7d1d5cSxiaofeibao } 650a7d1d5cSxiaofeibao ) 660a7d1d5cSxiaofeibao fuMapIQIdx.map { case (fu, iqidx) => 670a7d1d5cSxiaofeibao println(s"[NewDispatch] ${fu.name} $iqidx") 680a7d1d5cSxiaofeibao } 690a7d1d5cSxiaofeibao val sameIQIdxFus = fuMapIQIdx.map{ case (fu, iqidx) => 700a7d1d5cSxiaofeibao fuMapIQIdx.filter(_._2 == iqidx).map(_._1) -> iqidx 710a7d1d5cSxiaofeibao }.toSet.toSeq 720a7d1d5cSxiaofeibao val needMultiIQ = sameIQIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size > 1) 730a7d1d5cSxiaofeibao val needSingleIQ = sameIQIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size == 1) 740a7d1d5cSxiaofeibao needMultiIQ.map { case (fus, iqidx) => 750a7d1d5cSxiaofeibao println(s"[NewDispatch] needMultiIQ: ${fus.map(_.name)} $iqidx") 760a7d1d5cSxiaofeibao } 770a7d1d5cSxiaofeibao needSingleIQ.map { case (fus, iqidx) => 780a7d1d5cSxiaofeibao println(s"[NewDispatch] needSingleIQ: ${fus.map(_.name)} $iqidx") 790a7d1d5cSxiaofeibao } 800a7d1d5cSxiaofeibao val fuConfigsInExuParams = allExuParams.map(_.fuConfigs) 810a7d1d5cSxiaofeibao val fuMapExuIdx = sortedFuConfigs.map { case fu => { 820a7d1d5cSxiaofeibao val fuInExuIdx = fuConfigsInExuParams.zipWithIndex.filter { case (f, i) => f.contains(fu) }.map(_._2) 830a7d1d5cSxiaofeibao (fu -> fuInExuIdx) 840a7d1d5cSxiaofeibao } 850a7d1d5cSxiaofeibao } 860a7d1d5cSxiaofeibao val sameExuIdxFus = fuMapExuIdx.map { case (fu, exuidx) => 870a7d1d5cSxiaofeibao fuMapExuIdx.filter(_._2 == exuidx).map(_._1) -> exuidx 880a7d1d5cSxiaofeibao }.toSet.toSeq 890a7d1d5cSxiaofeibao val needMultiExu = sameExuIdxFus.sortBy(_._1.head.fuType.id).filter(_._2.size > 1).filter{ x => 900a7d1d5cSxiaofeibao x._1.map(y => fuMapIQIdx.filter(_._1 == y).head._2.size > 1).reduce(_ && _) 910a7d1d5cSxiaofeibao } 920a7d1d5cSxiaofeibao 930a7d1d5cSxiaofeibao val exuNum = allExuParams.size 940a7d1d5cSxiaofeibao val maxIQSize = allIssueParams.map(_.numEntries).max 950a7d1d5cSxiaofeibao val IQEnqSum = allIssueParams.map(_.numEnq).sum 960a7d1d5cSxiaofeibao 970a7d1d5cSxiaofeibao val io = IO(new Bundle { 980a7d1d5cSxiaofeibao // from rename 990a7d1d5cSxiaofeibao val renameIn = Vec(RenameWidth, Flipped(ValidIO(new DecodedInst))) 1000a7d1d5cSxiaofeibao val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new DynInst))) 1010a7d1d5cSxiaofeibao val toRenameAllFire = Output(Bool()) 1020a7d1d5cSxiaofeibao // enq Rob 1030a7d1d5cSxiaofeibao val enqRob = Flipped(new RobEnqIO) 1040a7d1d5cSxiaofeibao // IssueQueues 1050a7d1d5cSxiaofeibao val IQValidNumVec = Vec(exuNum, Input(UInt(maxIQSize.U.getWidth.W))) 1060a7d1d5cSxiaofeibao val toIssueQueues = Vec(IQEnqSum, DecoupledIO(new DynInst)) 1070a7d1d5cSxiaofeibao // to busyTable 1080a7d1d5cSxiaofeibao // set preg state to ready (write back regfile) 1090a7d1d5cSxiaofeibao val wbPregsInt = Vec(backendParams.numPregWb(IntData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 1100a7d1d5cSxiaofeibao val wbPregsFp = Vec(backendParams.numPregWb(FpData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 1110a7d1d5cSxiaofeibao val wbPregsVec = Vec(backendParams.numPregWb(VecData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 1120a7d1d5cSxiaofeibao val wbPregsV0 = Vec(backendParams.numPregWb(V0Data()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 1130a7d1d5cSxiaofeibao val wbPregsVl = Vec(backendParams.numPregWb(VlData()), Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 1140a7d1d5cSxiaofeibao val wakeUpAll = new Bundle { 1150a7d1d5cSxiaofeibao val wakeUpInt: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.intSchdParams.get.genIQWakeUpOutValidBundle) 1160a7d1d5cSxiaofeibao val wakeUpFp: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.fpSchdParams.get.genIQWakeUpOutValidBundle) 1170a7d1d5cSxiaofeibao val wakeUpVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.vfSchdParams.get.genIQWakeUpOutValidBundle) 1180a7d1d5cSxiaofeibao val wakeUpMem: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(backendParams.memSchdParams.get.genIQWakeUpOutValidBundle) 1190a7d1d5cSxiaofeibao } 1200a7d1d5cSxiaofeibao val og0Cancel = Input(ExuVec()) 1210a7d1d5cSxiaofeibao val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 1227edcfc93SZiyue Zhang // to vlbusytable 1237edcfc93SZiyue Zhang val vlWriteBackInfo = new Bundle { 1247edcfc93SZiyue Zhang val vlFromIntIsZero = Input(Bool()) 1257edcfc93SZiyue Zhang val vlFromIntIsVlmax = Input(Bool()) 1267edcfc93SZiyue Zhang val vlFromVfIsZero = Input(Bool()) 1277edcfc93SZiyue Zhang val vlFromVfIsVlmax = Input(Bool()) 1287edcfc93SZiyue Zhang } 1290a7d1d5cSxiaofeibao // from MemBlock 1300a7d1d5cSxiaofeibao val fromMem = new Bundle { 1310a7d1d5cSxiaofeibao val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 1320a7d1d5cSxiaofeibao val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 1330a7d1d5cSxiaofeibao val lqDeqPtr = Input(new LqPtr) 1340a7d1d5cSxiaofeibao val sqDeqPtr = Input(new SqPtr) 1350a7d1d5cSxiaofeibao // from lsq 1360a7d1d5cSxiaofeibao val lqCancelCnt = Input(UInt(log2Up(VirtualLoadQueueSize + 1).W)) 1370a7d1d5cSxiaofeibao val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 1380a7d1d5cSxiaofeibao } 1390a7d1d5cSxiaofeibao //toMem 1400a7d1d5cSxiaofeibao val toMem = new Bundle { 1410a7d1d5cSxiaofeibao val lsqEnqIO = Flipped(new LsqEnqIO) 1420a7d1d5cSxiaofeibao } 1430a7d1d5cSxiaofeibao // redirect 1440a7d1d5cSxiaofeibao val redirect = Flipped(ValidIO(new Redirect)) 1450a7d1d5cSxiaofeibao // singleStep 1460a7d1d5cSxiaofeibao val singleStep = Input(Bool()) 1470a7d1d5cSxiaofeibao // lfst 1480a7d1d5cSxiaofeibao val lfst = new DispatchLFSTIO 1490a7d1d5cSxiaofeibao 1500a7d1d5cSxiaofeibao // perf only 1510a7d1d5cSxiaofeibao val robHead = Input(new DynInst) 1520a7d1d5cSxiaofeibao val stallReason = Flipped(new StallReasonIO(RenameWidth)) 1530a7d1d5cSxiaofeibao val lqCanAccept = Input(Bool()) 1540a7d1d5cSxiaofeibao val sqCanAccept = Input(Bool()) 1550a7d1d5cSxiaofeibao val robHeadNotReady = Input(Bool()) 1560a7d1d5cSxiaofeibao val robFull = Input(Bool()) 1570a7d1d5cSxiaofeibao val debugTopDown = new Bundle { 1580a7d1d5cSxiaofeibao val fromRob = Flipped(new RobDispatchTopDownIO) 1590a7d1d5cSxiaofeibao val fromCore = new CoreDispatchTopDownIO 1600a7d1d5cSxiaofeibao } 1610a7d1d5cSxiaofeibao }) 1620a7d1d5cSxiaofeibao // Deq for std's IQ is not assigned in Dispatch2Iq, so add one more src for it. 1630a7d1d5cSxiaofeibao val issueBlockParams = backendParams.allIssueParams 1640a7d1d5cSxiaofeibao val renameIn = io.renameIn 1650a7d1d5cSxiaofeibao val fromRename = io.fromRename 1660a7d1d5cSxiaofeibao io.toRenameAllFire := io.fromRename.map(x => !x.valid || x.fire).reduce(_ && _) 1670a7d1d5cSxiaofeibao val fromRenameUpdate = Wire(Vec(RenameWidth, Flipped(ValidIO(new DynInst)))) 1680a7d1d5cSxiaofeibao fromRenameUpdate := fromRename 1690a7d1d5cSxiaofeibao val renameWidth = io.fromRename.size 1700a7d1d5cSxiaofeibao val issueQueueCount = io.IQValidNumVec 1710a7d1d5cSxiaofeibao val issueQueueNum = allIssueParams.size 1720a7d1d5cSxiaofeibao // int fp vec v0 vl 1730a7d1d5cSxiaofeibao val numRegType = 5 1740a7d1d5cSxiaofeibao val idxRegTypeInt = allFuConfigs.map(x => { 1750a7d1d5cSxiaofeibao x.srcData.map(xx => { 1760a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => IntRegSrcDataSet.contains(y._1)).map(_._2) 1770a7d1d5cSxiaofeibao }).flatten 1780a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 1790a7d1d5cSxiaofeibao val idxRegTypeFp = allFuConfigs.map(x => { 1800a7d1d5cSxiaofeibao x.srcData.map(xx => { 1810a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => FpRegSrcDataSet.contains(y._1)).map(_._2) 1820a7d1d5cSxiaofeibao }).flatten 1830a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 1840a7d1d5cSxiaofeibao val idxRegTypeVec = allFuConfigs.map(x => { 1850a7d1d5cSxiaofeibao x.srcData.map(xx => { 1860a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => VecRegSrcDataSet.contains(y._1)).map(_._2) 1870a7d1d5cSxiaofeibao }).flatten 1880a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 1890a7d1d5cSxiaofeibao val idxRegTypeV0 = allFuConfigs.map(x => { 1900a7d1d5cSxiaofeibao x.srcData.map(xx => { 1910a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => V0RegSrcDataSet.contains(y._1)).map(_._2) 1920a7d1d5cSxiaofeibao }).flatten 1930a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 1940a7d1d5cSxiaofeibao val idxRegTypeVl = allFuConfigs.map(x => { 1950a7d1d5cSxiaofeibao x.srcData.map(xx => { 1960a7d1d5cSxiaofeibao xx.zipWithIndex.filter(y => VlRegSrcDataSet.contains(y._1)).map(_._2) 1970a7d1d5cSxiaofeibao }).flatten 1980a7d1d5cSxiaofeibao }).flatten.toSet.toSeq.sorted 1990a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeInt: $idxRegTypeInt") 2000a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeFp: $idxRegTypeFp") 2010a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeVec: $idxRegTypeVec") 2020a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeV0: $idxRegTypeV0") 2030a7d1d5cSxiaofeibao println(s"[NewDispatch] idxRegTypeVl: $idxRegTypeVl") 2040a7d1d5cSxiaofeibao val numRegSrc: Int = issueBlockParams.map(_.exuBlockParams.map( 2050a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numRegSrc + 1 else x.numRegSrc 2060a7d1d5cSxiaofeibao ).max).max 2070a7d1d5cSxiaofeibao 2080a7d1d5cSxiaofeibao val numRegSrcInt: Int = issueBlockParams.map(_.exuBlockParams.map( 2090a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numIntSrc + 1 else x.numIntSrc 2100a7d1d5cSxiaofeibao ).max).max 2110a7d1d5cSxiaofeibao val numRegSrcFp: Int = issueBlockParams.map(_.exuBlockParams.map( 2120a7d1d5cSxiaofeibao x => if (x.hasStdFu) x.numFpSrc + 1 else x.numFpSrc 2130a7d1d5cSxiaofeibao ).max).max 2140a7d1d5cSxiaofeibao val numRegSrcVf: Int = issueBlockParams.map(_.exuBlockParams.map( 2150a7d1d5cSxiaofeibao x => x.numVecSrc 2160a7d1d5cSxiaofeibao ).max).max 2170a7d1d5cSxiaofeibao val numRegSrcV0: Int = issueBlockParams.map(_.exuBlockParams.map( 2180a7d1d5cSxiaofeibao x => x.numV0Src 2190a7d1d5cSxiaofeibao ).max).max 2200a7d1d5cSxiaofeibao val numRegSrcVl: Int = issueBlockParams.map(_.exuBlockParams.map( 2210a7d1d5cSxiaofeibao x => x.numVlSrc 2220a7d1d5cSxiaofeibao ).max).max 2230a7d1d5cSxiaofeibao 2240a7d1d5cSxiaofeibao println(s"[Dispatch2Iq] numRegSrc: ${numRegSrc}, numRegSrcInt: ${numRegSrcInt}, numRegSrcFp: ${numRegSrcFp}, " + 2250a7d1d5cSxiaofeibao s"numRegSrcVf: ${numRegSrcVf}, numRegSrcV0: ${numRegSrcV0}, numRegSrcVl: ${numRegSrcVl}") 2260a7d1d5cSxiaofeibao 2270a7d1d5cSxiaofeibao // RegCacheTagTable Module 2280a7d1d5cSxiaofeibao val rcTagTable = Module(new RegCacheTagTable(numRegSrcInt * renameWidth)) 2290a7d1d5cSxiaofeibao // BusyTable Modules 2300a7d1d5cSxiaofeibao val intBusyTable = Module(new BusyTable(numRegSrcInt * renameWidth, backendParams.numPregWb(IntData()), IntPhyRegs, IntWB())) 2310a7d1d5cSxiaofeibao val fpBusyTable = Module(new BusyTable(numRegSrcFp * renameWidth, backendParams.numPregWb(FpData()), FpPhyRegs, FpWB())) 2320a7d1d5cSxiaofeibao val vecBusyTable = Module(new BusyTable(numRegSrcVf * renameWidth, backendParams.numPregWb(VecData()), VfPhyRegs, VfWB())) 2330a7d1d5cSxiaofeibao val v0BusyTable = Module(new BusyTable(numRegSrcV0 * renameWidth, backendParams.numPregWb(V0Data()), V0PhyRegs, V0WB())) 2347edcfc93SZiyue Zhang val vlBusyTable = Module(new VlBusyTable(numRegSrcVl * renameWidth, backendParams.numPregWb(VlData()), VlPhyRegs, VlWB())) 2357edcfc93SZiyue Zhang vlBusyTable.io_vl_Wb.vlWriteBackInfo := io.vlWriteBackInfo 2360a7d1d5cSxiaofeibao val busyTables = Seq(intBusyTable, fpBusyTable, vecBusyTable, v0BusyTable, vlBusyTable) 2370a7d1d5cSxiaofeibao val wbPregs = Seq(io.wbPregsInt, io.wbPregsFp, io.wbPregsVec, io.wbPregsV0, io.wbPregsVl) 2380a7d1d5cSxiaofeibao val idxRegType = Seq(idxRegTypeInt, idxRegTypeFp, idxRegTypeVec, idxRegTypeV0, idxRegTypeVl) 2390a7d1d5cSxiaofeibao val allocPregsValid = Wire(Vec(busyTables.size, Vec(RenameWidth, Bool()))) 2400a7d1d5cSxiaofeibao allocPregsValid(0) := VecInit(fromRename.map(x => x.valid && x.bits.rfWen && !x.bits.eliminatedMove)) 2410a7d1d5cSxiaofeibao allocPregsValid(1) := VecInit(fromRename.map(x => x.valid && x.bits.fpWen)) 2420a7d1d5cSxiaofeibao allocPregsValid(2) := VecInit(fromRename.map(x => x.valid && x.bits.vecWen)) 2430a7d1d5cSxiaofeibao allocPregsValid(3) := VecInit(fromRename.map(x => x.valid && x.bits.v0Wen)) 2440a7d1d5cSxiaofeibao allocPregsValid(4) := VecInit(fromRename.map(x => x.valid && x.bits.vlWen)) 2450a7d1d5cSxiaofeibao val allocPregs = Wire(Vec(busyTables.size, Vec(RenameWidth, ValidIO(UInt(PhyRegIdxWidth.W))))) 2460a7d1d5cSxiaofeibao allocPregs.zip(allocPregsValid).map(x =>{ 2470a7d1d5cSxiaofeibao x._1.zip(x._2).zipWithIndex.map{case ((sink, source), i) => { 2480a7d1d5cSxiaofeibao sink.valid := source 2490a7d1d5cSxiaofeibao sink.bits := fromRename(i).bits.pdest 2500a7d1d5cSxiaofeibao }} 2510a7d1d5cSxiaofeibao }) 2520a7d1d5cSxiaofeibao val wakeUp = io.wakeUpAll.wakeUpInt ++ io.wakeUpAll.wakeUpFp ++ io.wakeUpAll.wakeUpVec ++ io.wakeUpAll.wakeUpMem 2530a7d1d5cSxiaofeibao busyTables.zip(wbPregs).zip(allocPregs).map{ case ((b, w), a) => { 2540a7d1d5cSxiaofeibao b.io.wakeUpInt := io.wakeUpAll.wakeUpInt 2550a7d1d5cSxiaofeibao b.io.wakeUpFp := io.wakeUpAll.wakeUpFp 2560a7d1d5cSxiaofeibao b.io.wakeUpVec := io.wakeUpAll.wakeUpVec 2570a7d1d5cSxiaofeibao b.io.wakeUpMem := io.wakeUpAll.wakeUpMem 2580a7d1d5cSxiaofeibao b.io.og0Cancel := io.og0Cancel 2590a7d1d5cSxiaofeibao b.io.ldCancel := io.ldCancel 2600a7d1d5cSxiaofeibao b.io.wbPregs := w 2610a7d1d5cSxiaofeibao b.io.allocPregs := a 2620a7d1d5cSxiaofeibao }} 2630a7d1d5cSxiaofeibao rcTagTable.io.allocPregs.zip(allocPregs(0)).map(x => x._1 := x._2) 2640a7d1d5cSxiaofeibao rcTagTable.io.wakeupFromIQ := io.wakeUpAll.wakeUpInt ++ io.wakeUpAll.wakeUpMem 2650a7d1d5cSxiaofeibao rcTagTable.io.og0Cancel := io.og0Cancel 2660a7d1d5cSxiaofeibao rcTagTable.io.ldCancel := io.ldCancel 2670a7d1d5cSxiaofeibao busyTables.zip(idxRegType).zipWithIndex.map { case ((b, idxseq), i) => { 2680a7d1d5cSxiaofeibao val readAddr = VecInit(fromRename.map(x => x.bits.psrc.zipWithIndex.filter(xx => idxseq.contains(xx._2)).map(_._1)).flatten) 2690a7d1d5cSxiaofeibao 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) 2700a7d1d5cSxiaofeibao b.io.read.map(_.req).zip(readAddr).map(x => x._1 := x._2) 2710a7d1d5cSxiaofeibao // only int src need srcLoadDependency, src0 src1 2720a7d1d5cSxiaofeibao if (i == 0) { 2730a7d1d5cSxiaofeibao val srcLoadDependencyUpdate = fromRenameUpdate.map(x => x.bits.srcLoadDependency.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 2740a7d1d5cSxiaofeibao val srcType = fromRenameUpdate.map(x => x.bits.srcType.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 2750a7d1d5cSxiaofeibao // for std, int src need srcLoadDependency, fp src donot need srcLoadDependency 2760a7d1d5cSxiaofeibao srcLoadDependencyUpdate.lazyZip(b.io.read.map(_.loadDependency)).lazyZip(srcType).map{ case (sink, source, srctype) => 2770a7d1d5cSxiaofeibao sink := Mux(SrcType.isXp(srctype), source, 0.U.asTypeOf(sink)) 2780a7d1d5cSxiaofeibao } 2790a7d1d5cSxiaofeibao // only int src need rcTag 2800a7d1d5cSxiaofeibao val rcTagUpdate = fromRenameUpdate.map(x => x.bits.regCacheIdx.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 2810a7d1d5cSxiaofeibao rcTagUpdate.zip(rcTagTable.io.readPorts.map(_.addr)).map(x => x._1 := x._2) 2820a7d1d5cSxiaofeibao val useRegCacheUpdate = fromRenameUpdate.map(x => x.bits.useRegCache.zipWithIndex.filter(x => idxseq.contains(x._2)).map(_._1)).flatten 2830a7d1d5cSxiaofeibao useRegCacheUpdate.zip(rcTagTable.io.readPorts.map(_.valid)).map(x => x._1 := x._2) 2840a7d1d5cSxiaofeibao rcTagTable.io.readPorts.map(_.ren).zip(readValid).map(x => x._1 := x._2) 2850a7d1d5cSxiaofeibao rcTagTable.io.readPorts.map(_.tag).zip(readAddr).map(x => x._1 := x._2) 2860a7d1d5cSxiaofeibao } 2870a7d1d5cSxiaofeibao }} 2880a7d1d5cSxiaofeibao val allSrcState = Wire(Vec(renameWidth, Vec(numRegSrc, Vec(numRegType, Bool())))) 2890a7d1d5cSxiaofeibao for (i <- 0 until renameWidth){ 2900a7d1d5cSxiaofeibao for (j <- 0 until numRegSrc){ 2910a7d1d5cSxiaofeibao for (k <- 0 until numRegType){ 2920a7d1d5cSxiaofeibao if (!idxRegType(k).contains(j)) { 2930a7d1d5cSxiaofeibao allSrcState(i)(j)(k) := false.B 2940a7d1d5cSxiaofeibao } 2950a7d1d5cSxiaofeibao else { 2960a7d1d5cSxiaofeibao val readidx = i * idxRegType(k).size + idxRegType(k).indexOf(j) 2970a7d1d5cSxiaofeibao val readEn = k match { 2980a7d1d5cSxiaofeibao case 0 => SrcType.isXp(fromRename(i).bits.srcType(j)) 2990a7d1d5cSxiaofeibao case 1 => SrcType.isFp(fromRename(i).bits.srcType(j)) 3000a7d1d5cSxiaofeibao case 2 => SrcType.isVp(fromRename(i).bits.srcType(j)) 3010a7d1d5cSxiaofeibao case 3 => SrcType.isV0(fromRename(i).bits.srcType(j)) 3020a7d1d5cSxiaofeibao case 4 => true.B 3030a7d1d5cSxiaofeibao } 3040a7d1d5cSxiaofeibao allSrcState(i)(j)(k) := readEn && busyTables(k).io.read(readidx).resp || SrcType.isImm(fromRename(i).bits.srcType(j)) 3050a7d1d5cSxiaofeibao } 3060a7d1d5cSxiaofeibao } 3070a7d1d5cSxiaofeibao } 3080a7d1d5cSxiaofeibao } 3090a7d1d5cSxiaofeibao 3107edcfc93SZiyue Zhang // eliminate old vd 3117edcfc93SZiyue Zhang val ignoreOldVdVec = Wire(Vec(renameWidth, Bool())) 3127edcfc93SZiyue Zhang for (i <- 0 until renameWidth){ 3137edcfc93SZiyue Zhang // numRegSrcVf - 1 is old vd 3147edcfc93SZiyue Zhang var j = numRegSrcVf - 1 3157edcfc93SZiyue Zhang // 2 is type of vec 3167edcfc93SZiyue Zhang var k = 2 3177edcfc93SZiyue Zhang val readidx = i * idxRegType(k).size + idxRegType(k).indexOf(j) 3187edcfc93SZiyue Zhang val readEn = SrcType.isVp(fromRename(i).bits.srcType(j)) 3197edcfc93SZiyue Zhang val isDependOldVd = fromRename(i).bits.vpu.isDependOldVd 3207edcfc93SZiyue Zhang val isWritePartVd = fromRename(i).bits.vpu.isWritePartVd 3217edcfc93SZiyue Zhang val vta = fromRename(i).bits.vpu.vta 3227edcfc93SZiyue Zhang val vma = fromRename(i).bits.vpu.vma 3237edcfc93SZiyue Zhang val vm = fromRename(i).bits.vpu.vm 3247edcfc93SZiyue Zhang val vlIsVlmax = vlBusyTable.io_vl_read.vlReadInfo(i).is_vlmax 325a2ecedc9SZiyue Zhang val vlIsNonZero = vlBusyTable.io_vl_read.vlReadInfo(i).is_nonzero 3267edcfc93SZiyue Zhang val ignoreTail = vlIsVlmax && (vm =/= 0.U || vma) && !isWritePartVd 3277edcfc93SZiyue Zhang val ignoreWhole = (vm =/= 0.U || vma) && vta 3287edcfc93SZiyue Zhang val ignoreOldVd = vlBusyTable.io.read(i).resp && vlIsNonZero && !isDependOldVd && (ignoreTail || ignoreWhole) 3297edcfc93SZiyue Zhang ignoreOldVdVec(i) := readEn && ignoreOldVd 3307edcfc93SZiyue Zhang allSrcState(i)(j)(k) := readEn && (busyTables(k).io.read(readidx).resp || ignoreOldVd) || SrcType.isImm(fromRename(i).bits.srcType(j)) 3317edcfc93SZiyue Zhang } 3327edcfc93SZiyue Zhang 333bcd0c45eSchengguanghui // Singlestep should only commit one machine instruction after dret, and then hart enter debugMode according to singlestep exception. 334bcd0c45eSchengguanghui val s_holdRobidx :: s_updateRobidx :: Nil = Enum(2) 335bcd0c45eSchengguanghui val singleStepState = RegInit(s_updateRobidx) 3360a7d1d5cSxiaofeibao 337bcd0c45eSchengguanghui val robidxStepNext = WireInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 338bcd0c45eSchengguanghui val robidxStepReg = RegInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 339bcd0c45eSchengguanghui val robidxCanCommitStepping = WireInit(0.U.asTypeOf(fromRename(0).bits.robIdx)) 340bcd0c45eSchengguanghui 341bcd0c45eSchengguanghui when(!io.singleStep) { 342bcd0c45eSchengguanghui singleStepState := s_updateRobidx 343bcd0c45eSchengguanghui }.elsewhen(io.singleStep && fromRename(0).fire && io.enqRob.req(0).valid) { 344bcd0c45eSchengguanghui singleStepState := s_holdRobidx 345bcd0c45eSchengguanghui robidxStepNext := fromRename(0).bits.robIdx 346bcd0c45eSchengguanghui } 347bcd0c45eSchengguanghui 348bcd0c45eSchengguanghui when(singleStepState === s_updateRobidx) { 349bcd0c45eSchengguanghui robidxStepReg := robidxStepNext 350bcd0c45eSchengguanghui robidxCanCommitStepping := robidxStepNext 351bcd0c45eSchengguanghui }.elsewhen(singleStepState === s_holdRobidx) { 352bcd0c45eSchengguanghui robidxStepReg := robidxStepReg 353bcd0c45eSchengguanghui robidxCanCommitStepping := robidxStepReg 354bcd0c45eSchengguanghui } 3550a7d1d5cSxiaofeibao 3560a7d1d5cSxiaofeibao val minIQSelAll = Wire(Vec(needMultiExu.size, Vec(renameWidth, Vec(issueQueueNum, Bool())))) 3570a7d1d5cSxiaofeibao needMultiExu.zipWithIndex.map{ case ((fus, exuidx), needMultiExuidx) => { 3580a7d1d5cSxiaofeibao val suffix = fus.map(_.name).mkString("_") 3590a7d1d5cSxiaofeibao val iqNum = exuidx.size 3600a7d1d5cSxiaofeibao val iqidx = allIssueParams.map(_.exuBlockParams.map(_.fuConfigs).flatten.toSet.toSeq).zipWithIndex.filter{x => fus.toSet.subsetOf(x._1.toSet)}.map(_._2) 3610a7d1d5cSxiaofeibao println(s"[NewDispatch] ${fus.map(_.name)};iqidx:$iqidx;exuIdx:$exuidx") 3620a7d1d5cSxiaofeibao val compareMatrix = Wire(Vec(iqNum, Vec(iqNum, Bool()))).suggestName(s"compareMatrix_$suffix") 3630a7d1d5cSxiaofeibao for (i <- 0 until iqNum) { 3640a7d1d5cSxiaofeibao for (j <- 0 until iqNum) { 3650a7d1d5cSxiaofeibao if (i == j) compareMatrix(i)(j) := false.B 3660a7d1d5cSxiaofeibao else if (i < j) compareMatrix(i)(j) := issueQueueCount(exuidx(i)) < issueQueueCount(exuidx(j)) 3670a7d1d5cSxiaofeibao else compareMatrix(i)(j) := !compareMatrix(j)(i) 3680a7d1d5cSxiaofeibao } 3690a7d1d5cSxiaofeibao } 3700a7d1d5cSxiaofeibao val IQSort = Reg(Vec(iqNum, Vec(iqNum, Bool()))).suggestName(s"IQSort_$suffix}") 3710a7d1d5cSxiaofeibao for (i <- 0 until iqNum){ 3720a7d1d5cSxiaofeibao // i = 0 minimum iq, i = iqNum - 1 -> maximum iq 3730a7d1d5cSxiaofeibao IQSort(i) := compareMatrix.map(x => PopCount(x) === (iqNum - 1 - i).U) 3740a7d1d5cSxiaofeibao } 3750a7d1d5cSxiaofeibao val minIQSel = Wire(Vec(renameWidth, Vec(issueQueueNum, Bool()))).suggestName(s"minIQSel_$suffix") 3760a7d1d5cSxiaofeibao for (i <- 0 until renameWidth){ 3770a7d1d5cSxiaofeibao val minIQSel_ith = IQSort(i % iqNum) 3780a7d1d5cSxiaofeibao println(s"minIQSel_${i}th_$suffix = IQSort(${i % iqNum})") 3790a7d1d5cSxiaofeibao for (j <- 0 until issueQueueNum){ 3800a7d1d5cSxiaofeibao minIQSel(i)(j) := false.B 3810a7d1d5cSxiaofeibao if (iqidx.contains(j)){ 3820a7d1d5cSxiaofeibao minIQSel(i)(j) := minIQSel_ith(iqidx.indexOf(j)) 3830a7d1d5cSxiaofeibao println(s"minIQSel_${suffix}_${i}_${j} = minIQSel_ith(iqidx.indexOf(${j}))") 3840a7d1d5cSxiaofeibao } 3850a7d1d5cSxiaofeibao } 3860a7d1d5cSxiaofeibao } 3870a7d1d5cSxiaofeibao minIQSelAll(needMultiExuidx) := minIQSel 3880a7d1d5cSxiaofeibao if (backendParams.debugEn){ 3890a7d1d5cSxiaofeibao dontTouch(compareMatrix) 3900a7d1d5cSxiaofeibao dontTouch(IQSort) 3910a7d1d5cSxiaofeibao dontTouch(minIQSel) 3920a7d1d5cSxiaofeibao } 3930a7d1d5cSxiaofeibao } 3940a7d1d5cSxiaofeibao } 3950a7d1d5cSxiaofeibao val fuConfigSeq = needMultiExu.map(_._1) 3960a7d1d5cSxiaofeibao val fuTypeOH = Wire(Vec(renameWidth, Vec(needMultiExu.size, Bool()))) 3970a7d1d5cSxiaofeibao fuTypeOH.zip(renameIn).map{ case(oh, in) => { 3980a7d1d5cSxiaofeibao oh := fuConfigSeq.map(x => x.map(xx => in.bits.fuType(xx.fuType.id)).reduce(_ || _) && in.valid) 3990a7d1d5cSxiaofeibao } 4000a7d1d5cSxiaofeibao } 4010a7d1d5cSxiaofeibao // not count itself 4020a7d1d5cSxiaofeibao val popFuTypeOH = Wire(Vec(renameWidth, Vec(needMultiExu.size, UInt((renameWidth-1).U.getWidth.W)))) 4030a7d1d5cSxiaofeibao popFuTypeOH.zipWithIndex.map{ case (pop, idx) => { 4040a7d1d5cSxiaofeibao if (idx == 0){ 4050a7d1d5cSxiaofeibao pop := 0.U.asTypeOf(pop) 4060a7d1d5cSxiaofeibao } 4070a7d1d5cSxiaofeibao else { 4080a7d1d5cSxiaofeibao pop.zipWithIndex.map{ case (p, i) => { 4090a7d1d5cSxiaofeibao p := PopCount(fuTypeOH.take(idx).map(x => x(i))) 4100a7d1d5cSxiaofeibao } 4110a7d1d5cSxiaofeibao } 4120a7d1d5cSxiaofeibao } 4130a7d1d5cSxiaofeibao }} 4140a7d1d5cSxiaofeibao val uopSelIQ = Reg(Vec(renameWidth, Vec(issueQueueNum, Bool()))) 4150a7d1d5cSxiaofeibao val fuTypeOHSingle = Wire(Vec(renameWidth, Vec(needSingleIQ.size, Bool()))) 4160a7d1d5cSxiaofeibao fuTypeOHSingle.zip(renameIn).map{ case (oh, in) => { 4170a7d1d5cSxiaofeibao oh := needSingleIQ.map(_._1).map(x => x.map(xx => in.valid && in.bits.fuType(xx.fuType.id)).reduce(_ || _)) 4180a7d1d5cSxiaofeibao }} 4190a7d1d5cSxiaofeibao val uopSelIQSingle = Wire(Vec(needSingleIQ.size, Vec(issueQueueNum, Bool()))) 4200a7d1d5cSxiaofeibao uopSelIQSingle := VecInit(needSingleIQ.map(_._2).flatten.map(x => VecInit((1.U(issueQueueNum.W) << x)(issueQueueNum-1, 0).asBools))) 4210a7d1d5cSxiaofeibao uopSelIQ.zipWithIndex.map{ case (u, i) => { 4220a7d1d5cSxiaofeibao when(io.toRenameAllFire){ 4230a7d1d5cSxiaofeibao u := Mux(renameIn(i).valid, 4240a7d1d5cSxiaofeibao Mux(fuTypeOH(i).asUInt.orR, 4250a7d1d5cSxiaofeibao Mux1H(fuTypeOH(i), minIQSelAll)(Mux1H(fuTypeOH(i), popFuTypeOH(i))), 4260a7d1d5cSxiaofeibao Mux1H(fuTypeOHSingle(i), uopSelIQSingle)), 4270a7d1d5cSxiaofeibao 0.U.asTypeOf(u) 4280a7d1d5cSxiaofeibao ) 4290a7d1d5cSxiaofeibao }.elsewhen(io.fromRename(i).fire){ 4300a7d1d5cSxiaofeibao u := 0.U.asTypeOf(u) 4310a7d1d5cSxiaofeibao } 4320a7d1d5cSxiaofeibao }} 4330a7d1d5cSxiaofeibao val uopSelIQMatrix = Wire(Vec(renameWidth, Vec(issueQueueNum, UInt(renameWidth.U.getWidth.W)))) 4340a7d1d5cSxiaofeibao uopSelIQMatrix.zipWithIndex.map{ case (u, i) => { 4350a7d1d5cSxiaofeibao u.zipWithIndex.map{ case (uu, j) => { 4360a7d1d5cSxiaofeibao uu := PopCount(uopSelIQ.take(i+1).map(x => x.zipWithIndex.filter(_._2 == j).map(_._1)).flatten) 4370a7d1d5cSxiaofeibao }} 4380a7d1d5cSxiaofeibao }} 4390a7d1d5cSxiaofeibao val IQSelUop = Wire(Vec(IQEnqSum, ValidIO(new DynInst))) 4400a7d1d5cSxiaofeibao val uopBlockByIQ = Wire(Vec(renameWidth, Bool())) 4410a7d1d5cSxiaofeibao val allowDispatch = Wire(Vec(renameWidth, Bool())) 4420a7d1d5cSxiaofeibao val thisCanActualOut = Wire(Vec(renameWidth, Bool())) 4430a7d1d5cSxiaofeibao val lsqCanAccept = Wire(Bool()) 4440a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth){ 4450a7d1d5cSxiaofeibao // update valid logic 4464f3aa2faSxiaofeibao fromRenameUpdate(i).valid := fromRename(i).valid && allowDispatch(i) && !uopBlockByIQ(i) && thisCanActualOut(i) && 447bcd0c45eSchengguanghui lsqCanAccept && !fromRename(i).bits.eliminatedMove && !fromRename(i).bits.hasException && !fromRenameUpdate(i).bits.singleStep 4480a7d1d5cSxiaofeibao fromRename(i).ready := allowDispatch(i) && !uopBlockByIQ(i) && thisCanActualOut(i) && lsqCanAccept 4497edcfc93SZiyue Zhang // update src type if eliminate old vd 4507edcfc93SZiyue Zhang fromRenameUpdate(i).bits.srcType(numRegSrcVf - 1) := Mux(ignoreOldVdVec(i), SrcType.no, fromRename(i).bits.srcType(numRegSrcVf - 1)) 4510a7d1d5cSxiaofeibao } 45241eedc8dSlinzhida for (i <- 0 until RenameWidth){ 45341eedc8dSlinzhida // check is drop amocas sta 4542c6839d1SNewPaulWalker fromRenameUpdate(i).bits.isDropAmocasSta := fromRename(i).bits.isAMOCAS && fromRename(i).bits.uopIdx(0) === 0.U 455bcd0c45eSchengguanghui // update singleStep 456bcd0c45eSchengguanghui fromRenameUpdate(i).bits.singleStep := io.singleStep && (fromRename(i).bits.robIdx =/= robidxCanCommitStepping) 45741eedc8dSlinzhida } 4580a7d1d5cSxiaofeibao var temp = 0 4590a7d1d5cSxiaofeibao allIssueParams.zipWithIndex.map{ case(issue, iqidx) => { 4600a7d1d5cSxiaofeibao for (i <- 0 until issue.numEnq){ 4610a7d1d5cSxiaofeibao val oh = Wire(Vec(renameWidth, Bool())).suggestName(s"oh_IQSelUop_$temp") 4620a7d1d5cSxiaofeibao oh := uopSelIQMatrix.map(_(iqidx)).map(_ === (i+1).U) 4630a7d1d5cSxiaofeibao IQSelUop(temp) := PriorityMux(oh, fromRenameUpdate) 4640a7d1d5cSxiaofeibao // there only assign valid not use PriorityMuxDefalut for better timing 4650a7d1d5cSxiaofeibao IQSelUop(temp).valid := PriorityMuxDefault(oh.zip(fromRenameUpdate.map(_.valid)), false.B) 4660a7d1d5cSxiaofeibao val allFuThisIQ = issue.exuBlockParams.map(_.fuConfigs).flatten.toSet.toSeq 4670a7d1d5cSxiaofeibao val hasStaFu = !allFuThisIQ.filter(_.name == "sta").isEmpty 4680a7d1d5cSxiaofeibao for (j <- 0 until numRegSrc){ 4690a7d1d5cSxiaofeibao val maskForStd = hasStaFu && (j == 1) 4700a7d1d5cSxiaofeibao val thisSrcHasInt = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) IntRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 4710a7d1d5cSxiaofeibao val thisSrcHasFp = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) FpRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 4720a7d1d5cSxiaofeibao val thisSrcHasVec = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) VecRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 4730a7d1d5cSxiaofeibao val thisSrcHasV0 = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) V0RegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 4740a7d1d5cSxiaofeibao val thisSrcHasVl = allFuThisIQ.map(x => {x.srcData.map(xx => {if (j < xx.size) VlRegSrcDataSet.contains(xx(j)) else false}).reduce(_ || _)}).reduce(_ || _) 4750a7d1d5cSxiaofeibao val selSrcState = Seq(thisSrcHasInt || maskForStd, thisSrcHasFp || maskForStd, thisSrcHasVec, thisSrcHasV0, thisSrcHasVl) 4760a7d1d5cSxiaofeibao IQSelUop(temp).bits.srcState(j) := PriorityMux(oh, allSrcState)(j).zip(selSrcState).filter(_._2 == true).map(_._1).foldLeft(false.B)(_ || _).asUInt 4770a7d1d5cSxiaofeibao } 4780a7d1d5cSxiaofeibao temp = temp + 1 4790a7d1d5cSxiaofeibao if (backendParams.debugEn){ 4800a7d1d5cSxiaofeibao dontTouch(oh) 4810a7d1d5cSxiaofeibao } 4820a7d1d5cSxiaofeibao } 4830a7d1d5cSxiaofeibao }} 4840a7d1d5cSxiaofeibao temp = 0 4850a7d1d5cSxiaofeibao val uopBlockMatrix = Wire(Vec(renameWidth, Vec(issueQueueNum, Bool()))) 4860a7d1d5cSxiaofeibao val uopBlockMatrixForAssign = allIssueParams.zipWithIndex.map { case (issue, iqidx) => { 4870a7d1d5cSxiaofeibao val result = uopSelIQMatrix.map(_(iqidx)).map(x => Mux(io.toIssueQueues(temp).ready, x > issue.numEnq.U, x.orR)) 4880a7d1d5cSxiaofeibao temp = temp + issue.numEnq 4890a7d1d5cSxiaofeibao result 4900a7d1d5cSxiaofeibao }}.transpose 4910a7d1d5cSxiaofeibao uopBlockMatrix.zip(uopBlockMatrixForAssign).map(x => x._1 := VecInit(x._2)) 4920a7d1d5cSxiaofeibao uopBlockByIQ := uopBlockMatrix.map(_.reduce(_ || _)) 4930a7d1d5cSxiaofeibao io.toIssueQueues.zip(IQSelUop).map(x => { 4940a7d1d5cSxiaofeibao x._1.valid := x._2.valid 4950a7d1d5cSxiaofeibao x._1.bits := x._2.bits 4960a7d1d5cSxiaofeibao }) 4970a7d1d5cSxiaofeibao if (backendParams.debugEn){ 4980a7d1d5cSxiaofeibao dontTouch(uopSelIQMatrix) 4990a7d1d5cSxiaofeibao dontTouch(IQSelUop) 5000a7d1d5cSxiaofeibao dontTouch(fromRenameUpdate) 5010a7d1d5cSxiaofeibao dontTouch(uopBlockByIQ) 5020a7d1d5cSxiaofeibao dontTouch(allowDispatch) 5030a7d1d5cSxiaofeibao dontTouch(thisCanActualOut) 5040a7d1d5cSxiaofeibao dontTouch(popFuTypeOH) 5050a7d1d5cSxiaofeibao dontTouch(fuTypeOH) 5060a7d1d5cSxiaofeibao dontTouch(fuTypeOHSingle) 5070a7d1d5cSxiaofeibao dontTouch(minIQSelAll) 5080a7d1d5cSxiaofeibao } 5090a7d1d5cSxiaofeibao /////////////////////////////////////////////////////////// 5100a7d1d5cSxiaofeibao 5110a7d1d5cSxiaofeibao val lsqEnqCtrl = Module(new LsqEnqCtrl) 5120a7d1d5cSxiaofeibao 5130a7d1d5cSxiaofeibao // TODO: check lsqEnqCtrl redirect logic 5140a7d1d5cSxiaofeibao // here is RegNext because dispatch2iq use s2_s4_redirect, newDispatch use s1_s3_redirect 5150a7d1d5cSxiaofeibao lsqEnqCtrl.io.redirect := RegNext(io.redirect) 5160a7d1d5cSxiaofeibao lsqEnqCtrl.io.lcommit := io.fromMem.lcommit 5170a7d1d5cSxiaofeibao lsqEnqCtrl.io.scommit := io.fromMem.scommit 5180a7d1d5cSxiaofeibao lsqEnqCtrl.io.lqCancelCnt := io.fromMem.lqCancelCnt 5190a7d1d5cSxiaofeibao lsqEnqCtrl.io.sqCancelCnt := io.fromMem.sqCancelCnt 5200a7d1d5cSxiaofeibao lsqEnqCtrl.io.enq.iqAccept := io.fromRename.map(x => !x.valid || x.fire) 5210a7d1d5cSxiaofeibao io.toMem.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 5220a7d1d5cSxiaofeibao 5230a7d1d5cSxiaofeibao private val enqLsqIO = lsqEnqCtrl.io.enq 5240a7d1d5cSxiaofeibao private val lqFreeCount = lsqEnqCtrl.io.lqFreeCount 5250a7d1d5cSxiaofeibao private val sqFreeCount = lsqEnqCtrl.io.sqFreeCount 5260a7d1d5cSxiaofeibao 5270a7d1d5cSxiaofeibao private val numLoadDeq = LSQLdEnqWidth 5280a7d1d5cSxiaofeibao private val numStoreAMODeq = LSQStEnqWidth 5290a7d1d5cSxiaofeibao private val numVLoadDeq = LoadPipelineWidth 5300a7d1d5cSxiaofeibao private val numDeq = enqLsqIO.req.size 5310a7d1d5cSxiaofeibao lsqCanAccept := enqLsqIO.canAccept 5320a7d1d5cSxiaofeibao 5330a7d1d5cSxiaofeibao private val isLoadVec = VecInit(fromRename.map(x => x.valid && FuType.isLoad(x.bits.fuType))) 5340a7d1d5cSxiaofeibao private val isStoreVec = VecInit(fromRename.map(x => x.valid && FuType.isStore(x.bits.fuType))) 5350a7d1d5cSxiaofeibao private val isAMOVec = fromRename.map(x => x.valid && FuType.isAMO(x.bits.fuType)) 5360a7d1d5cSxiaofeibao private val isStoreAMOVec = fromRename.map(x => x.valid && (FuType.isStore(x.bits.fuType) || FuType.isAMO(x.bits.fuType))) 5370a7d1d5cSxiaofeibao private val isVLoadVec = VecInit(fromRename.map(x => x.valid && FuType.isVLoad(x.bits.fuType))) 5380a7d1d5cSxiaofeibao private val isVStoreVec = VecInit(fromRename.map(x => x.valid && FuType.isVStore(x.bits.fuType))) 5390a7d1d5cSxiaofeibao 5400a7d1d5cSxiaofeibao private val loadCntVec = VecInit(isLoadVec.indices.map(x => PopCount(isLoadVec.slice(0, x + 1)))) 5410a7d1d5cSxiaofeibao private val storeAMOCntVec = VecInit(isStoreAMOVec.indices.map(x => PopCount(isStoreAMOVec.slice(0, x + 1)))) 5420a7d1d5cSxiaofeibao private val vloadCntVec = VecInit(isVLoadVec.indices.map(x => PopCount(isVLoadVec.slice(0, x + 1)))) 5430a7d1d5cSxiaofeibao 5440a7d1d5cSxiaofeibao private val s0_enqLsq_resp = Wire(enqLsqIO.resp.cloneType) 5450a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 5460a7d1d5cSxiaofeibao // update lqIdx sqIdx 5470a7d1d5cSxiaofeibao fromRenameUpdate(i).bits.lqIdx := s0_enqLsq_resp(i).lqIdx 5480a7d1d5cSxiaofeibao fromRenameUpdate(i).bits.sqIdx := s0_enqLsq_resp(i).sqIdx 5490a7d1d5cSxiaofeibao } 5500a7d1d5cSxiaofeibao 5510a7d1d5cSxiaofeibao val loadBlockVec = VecInit(loadCntVec.map(_ > numLoadDeq.U)) 5520a7d1d5cSxiaofeibao val storeAMOBlockVec = VecInit(storeAMOCntVec.map(_ > numStoreAMODeq.U)) 5530a7d1d5cSxiaofeibao val vloadBlockVec = VecInit(vloadCntVec.map(_ > numVLoadDeq.U)) 5540a7d1d5cSxiaofeibao val lsStructBlockVec = VecInit((loadBlockVec.zip(storeAMOBlockVec)).zip(vloadBlockVec).map(x => x._1._1 || x._1._2 || x._2)) 5550a7d1d5cSxiaofeibao if (backendParams.debugEn) { 5560a7d1d5cSxiaofeibao dontTouch(loadBlockVec) 5570a7d1d5cSxiaofeibao dontTouch(storeAMOBlockVec) 5580a7d1d5cSxiaofeibao dontTouch(lsStructBlockVec) 5590a7d1d5cSxiaofeibao dontTouch(vloadBlockVec) 5600a7d1d5cSxiaofeibao dontTouch(isLoadVec) 5610a7d1d5cSxiaofeibao dontTouch(isVLoadVec) 5620a7d1d5cSxiaofeibao dontTouch(loadCntVec) 5630a7d1d5cSxiaofeibao } 5640a7d1d5cSxiaofeibao 5650a7d1d5cSxiaofeibao private val uop = fromRename.map(_.bits) 5660a7d1d5cSxiaofeibao private val fuType = uop.map(_.fuType) 5670a7d1d5cSxiaofeibao private val fuOpType = uop.map(_.fuOpType) 5680a7d1d5cSxiaofeibao private val vtype = uop.map(_.vpu.vtype) 5690a7d1d5cSxiaofeibao private val sew = vtype.map(_.vsew) 5700a7d1d5cSxiaofeibao private val lmul = vtype.map(_.vlmul) 5710a7d1d5cSxiaofeibao private val eew = uop.map(_.vpu.veew) 5720a7d1d5cSxiaofeibao private val mop = fuOpType.map(fuOpTypeItem => LSUOpType.getVecLSMop(fuOpTypeItem)) 5730a7d1d5cSxiaofeibao private val nf = fuOpType.zip(uop.map(_.vpu.nf)).map { case (fuOpTypeItem, nfItem) => Mux(LSUOpType.isWhole(fuOpTypeItem), 0.U, nfItem) } 5740a7d1d5cSxiaofeibao private val emul = fuOpType.zipWithIndex.map { case (fuOpTypeItem, index) => 5750a7d1d5cSxiaofeibao Mux( 5760a7d1d5cSxiaofeibao LSUOpType.isWhole(fuOpTypeItem), 5770a7d1d5cSxiaofeibao GenUSWholeEmul(nf(index)), 5780a7d1d5cSxiaofeibao Mux( 5790a7d1d5cSxiaofeibao LSUOpType.isMasked(fuOpTypeItem), 5800a7d1d5cSxiaofeibao 0.U(mulBits.W), 5810a7d1d5cSxiaofeibao EewLog2(eew(index)) - sew(index) + lmul(index) 5820a7d1d5cSxiaofeibao ) 5830a7d1d5cSxiaofeibao ) 5840a7d1d5cSxiaofeibao } 5850a7d1d5cSxiaofeibao 5860a7d1d5cSxiaofeibao private val isVlsType = fuType.map(fuTypeItem => FuType.isVls(fuTypeItem)).zip(fromRename.map(_.valid)).map(x => x._1 && x._2) 5874e7f9e52Sxiaofeibao private val isLSType = fuType.map(fuTypeItem => FuType.isLoad(fuTypeItem) || FuType.isStore(fuTypeItem)).zip(fromRename.map(_.valid)).map(x => x._1 && x._2) 5880a7d1d5cSxiaofeibao private val isSegment = fuType.map(fuTypeItem => FuType.isVsegls(fuTypeItem)).zip(fromRename.map(_.valid)).map(x => x._1 && x._2) 5890a7d1d5cSxiaofeibao // TODO 5900a7d1d5cSxiaofeibao private val isUnitStride = fuOpType.map(fuOpTypeItem => LSUOpType.isAllUS(fuOpTypeItem)) 5910a7d1d5cSxiaofeibao private val isVecUnitType = isVlsType.zip(isUnitStride).map { case (isVlsTypeItme, isUnitStrideItem) => 5920a7d1d5cSxiaofeibao isVlsTypeItme && isUnitStrideItem 5930a7d1d5cSxiaofeibao } 5940a7d1d5cSxiaofeibao private val isfofFixVlUop = uop.map { x => x.vpu.isVleff && x.lastUop } 5950a7d1d5cSxiaofeibao private val instType = isSegment.zip(mop).map { case (isSegementItem, mopItem) => Cat(isSegementItem, mopItem) } 5960a7d1d5cSxiaofeibao // There is no way to calculate the 'flow' for 'unit-stride' exactly: 5970a7d1d5cSxiaofeibao // Whether 'unit-stride' needs to be split can only be known after obtaining the address. 5980a7d1d5cSxiaofeibao // For scalar instructions, this is not handled here, and different assignments are done later according to the situation. 5990a7d1d5cSxiaofeibao private val numLsElem = VecInit(uop.map(_.numLsElem)) 6000a7d1d5cSxiaofeibao 6010a7d1d5cSxiaofeibao // The maximum 'numLsElem' number that can be emitted per port is: 6020a7d1d5cSxiaofeibao // 16 2 2 2 2 2. 6030a7d1d5cSxiaofeibao // The 'allowDispatch' calculations are done conservatively for timing purposes: 6040a7d1d5cSxiaofeibao // The Flow of scalar instructions is considered 1, 6050a7d1d5cSxiaofeibao // The flow of vector 'unit-stride' instructions is considered 2, and the flow of other vector instructions is considered 16. 6064e7f9e52Sxiaofeibao private val conserveFlows = VecInit(isVlsType.zip(isLSType).zipWithIndex.map { case ((isVlsTyepItem, isLSTypeItem), index) => 6070a7d1d5cSxiaofeibao Mux( 6080a7d1d5cSxiaofeibao isVlsTyepItem, 6094e7f9e52Sxiaofeibao Mux(isUnitStride(index), VecMemUnitStrideMaxFlowNum.U, 16.U), 6104e7f9e52Sxiaofeibao Mux(isLSTypeItem, 1.U, 0.U) 6110a7d1d5cSxiaofeibao ) 6124e7f9e52Sxiaofeibao }) 6130a7d1d5cSxiaofeibao 61494ec67d3Sxiaofeibao private val conserveFlowsIs16 = VecInit(isVlsType.zipWithIndex.map { case (isVlsTyepItem, index) => 61594ec67d3Sxiaofeibao isVlsTyepItem && !isUnitStride(index) 61694ec67d3Sxiaofeibao }) 61794ec67d3Sxiaofeibao private val conserveFlowsIs2 = VecInit(isVlsType.zipWithIndex.map { case (isVlsTyepItem, index) => 61894ec67d3Sxiaofeibao isVlsTyepItem && isUnitStride(index) 61994ec67d3Sxiaofeibao }) 62094ec67d3Sxiaofeibao private val conserveFlowsIs1 = VecInit(isLSType.zipWithIndex.map { case (isLSTyepItem, index) => 62194ec67d3Sxiaofeibao isLSTyepItem 62294ec67d3Sxiaofeibao }) 62394ec67d3Sxiaofeibao private val flowTotalWidth = (VecMemLSQEnqIteratorNumberSeq.max * RenameWidth).U.getWidth 62494ec67d3Sxiaofeibao private val conserveFlowTotalDispatch = Wire(Vec(RenameWidth, UInt(flowTotalWidth.W))) 62594ec67d3Sxiaofeibao private val lowCountMaxWidth = (2 * RenameWidth).U.getWidth 62694ec67d3Sxiaofeibao conserveFlowTotalDispatch.zipWithIndex.map{ case (flowTotal, idx) => 62794ec67d3Sxiaofeibao val highCount = PopCount(conserveFlowsIs16.take(idx + 1)) 62894ec67d3Sxiaofeibao val conserveFlowsIs2Or1 = VecInit(conserveFlowsIs2.zip(conserveFlowsIs1).map(x => Cat(x._1, x._2))) 62994ec67d3Sxiaofeibao val lowCount = conserveFlowsIs2Or1.take(idx + 1).reduce(_ +& _).asTypeOf(0.U(lowCountMaxWidth.W)) 63094ec67d3Sxiaofeibao flowTotal := (if (RenameWidth == 6) Cat(highCount, lowCount) else ((highCount << 4).asUInt + lowCount)) 63194ec67d3Sxiaofeibao } 63294ec67d3Sxiaofeibao // renameIn 63394ec67d3Sxiaofeibao private val isVlsTypeRename = io.renameIn.map(x => x.valid && FuType.isVls(x.bits.fuType)) 63494ec67d3Sxiaofeibao private val isLSTypeRename = io.renameIn.map(x => x.valid && (FuType.isLoad(x.bits.fuType)) || FuType.isStore(x.bits.fuType)) 63594ec67d3Sxiaofeibao private val isUnitStrideRename = io.renameIn.map(x => LSUOpType.isAllUS(x.bits.fuOpType)) 63694ec67d3Sxiaofeibao private val conserveFlowsIs16Rename = VecInit(isVlsTypeRename.zipWithIndex.map { case (isVlsTyepItem, index) => 63794ec67d3Sxiaofeibao isVlsTyepItem && !isUnitStrideRename(index) 63894ec67d3Sxiaofeibao }) 63994ec67d3Sxiaofeibao private val conserveFlowsIs2Rename = VecInit(isVlsTypeRename.zipWithIndex.map { case (isVlsTyepItem, index) => 64094ec67d3Sxiaofeibao isVlsTyepItem && isUnitStrideRename(index) 64194ec67d3Sxiaofeibao }) 64294ec67d3Sxiaofeibao private val conserveFlowsIs1Rename = VecInit(isLSTypeRename.zipWithIndex.map { case (isLSTyepItem, index) => 64394ec67d3Sxiaofeibao isLSTyepItem 64494ec67d3Sxiaofeibao }) 64594ec67d3Sxiaofeibao private val conserveFlowTotalRename = Wire(Vec(RenameWidth, UInt(flowTotalWidth.W))) 64694ec67d3Sxiaofeibao conserveFlowTotalRename.zipWithIndex.map { case (flowTotal, idx) => 64794ec67d3Sxiaofeibao val highCount = PopCount(conserveFlowsIs16Rename.take(idx + 1)) 64894ec67d3Sxiaofeibao val conserveFlowsIs2Or1 = VecInit(conserveFlowsIs2Rename.zip(conserveFlowsIs1Rename).map(x => Cat(x._1, x._2))) 64994ec67d3Sxiaofeibao val lowCount = conserveFlowsIs2Or1.take(idx + 1).reduce(_ +& _).asTypeOf(0.U(lowCountMaxWidth.W)) 65094ec67d3Sxiaofeibao flowTotal := (if (RenameWidth == 6) Cat(highCount, lowCount) else ((highCount << 4).asUInt + lowCount)) 65194ec67d3Sxiaofeibao } 65294ec67d3Sxiaofeibao 65394ec67d3Sxiaofeibao 65494ec67d3Sxiaofeibao private val conserveFlowTotal = Reg(Vec(RenameWidth, UInt(flowTotalWidth.W))) 65594ec67d3Sxiaofeibao when(io.toRenameAllFire){ 65694ec67d3Sxiaofeibao conserveFlowTotal := conserveFlowTotalRename 65794ec67d3Sxiaofeibao }.otherwise( 65894ec67d3Sxiaofeibao conserveFlowTotal := conserveFlowTotalDispatch 65994ec67d3Sxiaofeibao ) 6600a7d1d5cSxiaofeibao // A conservative allocation strategy is adopted here. 6610a7d1d5cSxiaofeibao // Vector 'unit-stride' instructions and scalar instructions can be issued from all six ports, 6620a7d1d5cSxiaofeibao // while other vector instructions can only be issued from the first port 6630a7d1d5cSxiaofeibao // if is segment instruction, need disptch it to Vldst_RS0, so, except port 0, stall other. 6640a7d1d5cSxiaofeibao // The allocation needs to meet a few conditions: 6650a7d1d5cSxiaofeibao // 1) The lsq has enough entris. 6660a7d1d5cSxiaofeibao // 2) The number of flows accumulated does not exceed VecMemDispatchMaxNumber. 6670a7d1d5cSxiaofeibao // 3) Vector instructions other than 'unit-stride' can only be issued on the first port. 6680a7d1d5cSxiaofeibao 6690a7d1d5cSxiaofeibao 6700a7d1d5cSxiaofeibao for (index <- allowDispatch.indices) { 67194ec67d3Sxiaofeibao val flowTotal = conserveFlowTotal(index) 6724e7f9e52Sxiaofeibao val allowDispatchPrevious = if (index == 0) true.B else allowDispatch(index - 1) 6730a7d1d5cSxiaofeibao when(isStoreVec(index) || isVStoreVec(index)) { 67494ec67d3Sxiaofeibao allowDispatch(index) := (sqFreeCount > flowTotal) && allowDispatchPrevious 6750a7d1d5cSxiaofeibao }.elsewhen(isLoadVec(index) || isVLoadVec(index)) { 67694ec67d3Sxiaofeibao allowDispatch(index) := (lqFreeCount > flowTotal) && allowDispatchPrevious 6770a7d1d5cSxiaofeibao }.elsewhen(isAMOVec(index)) { 6784e7f9e52Sxiaofeibao allowDispatch(index) := allowDispatchPrevious 6790a7d1d5cSxiaofeibao }.otherwise { 6804e7f9e52Sxiaofeibao allowDispatch(index) := allowDispatchPrevious 6810a7d1d5cSxiaofeibao } 6820a7d1d5cSxiaofeibao } 6830a7d1d5cSxiaofeibao 6840a7d1d5cSxiaofeibao 6850a7d1d5cSxiaofeibao // enqLsq io 6860a7d1d5cSxiaofeibao require(enqLsqIO.req.size == enqLsqIO.resp.size) 6870a7d1d5cSxiaofeibao for (i <- enqLsqIO.req.indices) { 6880a7d1d5cSxiaofeibao when(!io.fromRename(i).fire) { 6890a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 0.U 6900a7d1d5cSxiaofeibao }.elsewhen(isStoreVec(i) || isVStoreVec(i)) { 6910a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 2.U // store | vstore 6920a7d1d5cSxiaofeibao }.elsewhen(isLoadVec(i) || isVLoadVec(i)){ 6930a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 1.U // load | vload 6940a7d1d5cSxiaofeibao }.otherwise { 6950a7d1d5cSxiaofeibao enqLsqIO.needAlloc(i) := 0.U 6960a7d1d5cSxiaofeibao } 6970a7d1d5cSxiaofeibao enqLsqIO.req(i).valid := io.fromRename(i).fire && !isAMOVec(i) && !isSegment(i) && !isfofFixVlUop(i) 6980a7d1d5cSxiaofeibao enqLsqIO.req(i).bits := io.fromRename(i).bits 6990a7d1d5cSxiaofeibao 7000a7d1d5cSxiaofeibao // This is to make it easier to calculate in LSQ. 7010a7d1d5cSxiaofeibao // Both scalar instructions and vector instructions with FLOW equal to 1 have a NUM value of 1.” 7020a7d1d5cSxiaofeibao // But, the 'numLsElem' that is not a vector is set to 0 when passed to IQ 7030a7d1d5cSxiaofeibao enqLsqIO.req(i).bits.numLsElem := Mux(isVlsType(i), numLsElem(i), 1.U) 7040a7d1d5cSxiaofeibao s0_enqLsq_resp(i) := enqLsqIO.resp(i) 7050a7d1d5cSxiaofeibao } 7060a7d1d5cSxiaofeibao 7070a7d1d5cSxiaofeibao val isFp = VecInit(fromRename.map(req => FuType.isFArith(req.bits.fuType))) 7080a7d1d5cSxiaofeibao val isVec = VecInit(fromRename.map(req => FuType.isVArith (req.bits.fuType) || 7090a7d1d5cSxiaofeibao FuType.isVsetRvfWvf(req.bits.fuType))) 7100a7d1d5cSxiaofeibao val isMem = VecInit(fromRename.map(req => FuType.isMem(req.bits.fuType) || 7110a7d1d5cSxiaofeibao FuType.isVls (req.bits.fuType))) 7120a7d1d5cSxiaofeibao val isLs = VecInit(fromRename.map(req => FuType.isLoadStore(req.bits.fuType))) 7130a7d1d5cSxiaofeibao val isVls = VecInit(fromRename.map(req => FuType.isVls (req.bits.fuType))) 7140a7d1d5cSxiaofeibao val isStore = VecInit(fromRename.map(req => FuType.isStore(req.bits.fuType))) 7150a7d1d5cSxiaofeibao val isVStore = VecInit(fromRename.map(req => FuType.isVStore(req.bits.fuType))) 7160a7d1d5cSxiaofeibao val isAMO = VecInit(fromRename.map(req => FuType.isAMO(req.bits.fuType))) 7170a7d1d5cSxiaofeibao val isBlockBackward = VecInit(fromRename.map(x => x.valid && x.bits.blockBackward)) 7180a7d1d5cSxiaofeibao val isWaitForward = VecInit(fromRename.map(x => x.valid && x.bits.waitForward)) 7190a7d1d5cSxiaofeibao 7200a7d1d5cSxiaofeibao val updatedUop = Wire(Vec(RenameWidth, new DynInst)) 7210a7d1d5cSxiaofeibao val checkpoint_id = RegInit(0.U(64.W)) 7220a7d1d5cSxiaofeibao checkpoint_id := checkpoint_id + PopCount((0 until RenameWidth).map(i => 7230a7d1d5cSxiaofeibao fromRename(i).fire 7240a7d1d5cSxiaofeibao )) 7250a7d1d5cSxiaofeibao 7260a7d1d5cSxiaofeibao 7270a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 7280a7d1d5cSxiaofeibao 7290a7d1d5cSxiaofeibao updatedUop(i) := fromRename(i).bits 7300a7d1d5cSxiaofeibao updatedUop(i).debugInfo.eliminatedMove := fromRename(i).bits.eliminatedMove 7310a7d1d5cSxiaofeibao // For the LUI instruction: psrc(0) is from register file and should always be zero. 7320a7d1d5cSxiaofeibao when (fromRename(i).bits.isLUI) { 7330a7d1d5cSxiaofeibao updatedUop(i).psrc(0) := 0.U 7340a7d1d5cSxiaofeibao } 7350a7d1d5cSxiaofeibao //TODO: vec ls mdp 7360a7d1d5cSxiaofeibao io.lfst.req(i).valid := fromRename(i).fire && updatedUop(i).storeSetHit 7370a7d1d5cSxiaofeibao io.lfst.req(i).bits.isstore := isStore(i) 7380a7d1d5cSxiaofeibao io.lfst.req(i).bits.ssid := updatedUop(i).ssid 7390a7d1d5cSxiaofeibao io.lfst.req(i).bits.robIdx := updatedUop(i).robIdx // speculatively assigned in rename 7400a7d1d5cSxiaofeibao 7410a7d1d5cSxiaofeibao // override load delay ctrl signal with store set result 7420a7d1d5cSxiaofeibao if(StoreSetEnable) { 7430a7d1d5cSxiaofeibao updatedUop(i).loadWaitBit := io.lfst.resp(i).bits.shouldWait 7440a7d1d5cSxiaofeibao updatedUop(i).waitForRobIdx := io.lfst.resp(i).bits.robIdx 7450a7d1d5cSxiaofeibao } else { 7460a7d1d5cSxiaofeibao updatedUop(i).loadWaitBit := isLs(i) && !isStore(i) && fromRename(i).bits.loadWaitBit 7470a7d1d5cSxiaofeibao } 7480a7d1d5cSxiaofeibao // // update singleStep, singleStep exception only enable in next machine instruction. 7490a7d1d5cSxiaofeibao updatedUop(i).singleStep := io.singleStep && (fromRename(i).bits.robIdx =/= robidxCanCommitStepping) 7501eb8dd22SKunlin You XSDebug( 7511eb8dd22SKunlin You fromRename(i).fire && 7521eb8dd22SKunlin You (TriggerAction.isDmode(updatedUop(i).trigger) || updatedUop(i).exceptionVec(breakPoint)), s"Debug Mode: inst ${i} has frontend trigger exception\n") 7531eb8dd22SKunlin You XSDebug(fromRename(i).fire && updatedUop(i).singleStep, s"Debug Mode: inst ${i} has single step exception\n") 7540a7d1d5cSxiaofeibao if (env.EnableDifftest) { 7550a7d1d5cSxiaofeibao // debug runahead hint 7560a7d1d5cSxiaofeibao val debug_runahead_checkpoint_id = Wire(checkpoint_id.cloneType) 7570a7d1d5cSxiaofeibao if(i == 0){ 7580a7d1d5cSxiaofeibao debug_runahead_checkpoint_id := checkpoint_id 7590a7d1d5cSxiaofeibao } else { 7600a7d1d5cSxiaofeibao debug_runahead_checkpoint_id := checkpoint_id + PopCount((0 until i).map(i => 7610a7d1d5cSxiaofeibao fromRename(i).fire 7620a7d1d5cSxiaofeibao )) 7630a7d1d5cSxiaofeibao } 7640a7d1d5cSxiaofeibao } 7650a7d1d5cSxiaofeibao } 7660a7d1d5cSxiaofeibao 7670a7d1d5cSxiaofeibao // store set perf count 7680a7d1d5cSxiaofeibao XSPerfAccumulate("waittable_load_wait", PopCount((0 until RenameWidth).map(i => 7690a7d1d5cSxiaofeibao fromRename(i).fire && fromRename(i).bits.loadWaitBit && !isStore(i) && isLs(i) 7700a7d1d5cSxiaofeibao ))) 7710a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_load_wait", PopCount((0 until RenameWidth).map(i => 7720a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && !isStore(i) && isLs(i) 7730a7d1d5cSxiaofeibao ))) 7740a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_load_strict_wait", PopCount((0 until RenameWidth).map(i => 7750a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && updatedUop(i).loadWaitStrict && !isStore(i) && isLs(i) 7760a7d1d5cSxiaofeibao ))) 7770a7d1d5cSxiaofeibao XSPerfAccumulate("storeset_store_wait", PopCount((0 until RenameWidth).map(i => 7780a7d1d5cSxiaofeibao fromRename(i).fire && updatedUop(i).loadWaitBit && isStore(i) 7790a7d1d5cSxiaofeibao ))) 7800a7d1d5cSxiaofeibao 7810a7d1d5cSxiaofeibao val allResourceReady = io.enqRob.canAccept 7820a7d1d5cSxiaofeibao 7830a7d1d5cSxiaofeibao // Instructions should enter dispatch queues in order. 7840a7d1d5cSxiaofeibao // blockedByWaitForward: this instruction is blocked by itself (based on waitForward) 7850a7d1d5cSxiaofeibao // nextCanOut: next instructions can out (based on blockBackward) 7860a7d1d5cSxiaofeibao // notBlockedByPrevious: previous instructions can enqueue 7870a7d1d5cSxiaofeibao val hasException = VecInit(fromRename.zip(updatedUop).map { 7880a7d1d5cSxiaofeibao case (fromRename: DecoupledIO[DynInst], uop: DynInst) => 7890a7d1d5cSxiaofeibao fromRename.bits.hasException || uop.singleStep 7900a7d1d5cSxiaofeibao }) 7910a7d1d5cSxiaofeibao 7920a7d1d5cSxiaofeibao private val blockedByWaitForward = Wire(Vec(RenameWidth, Bool())) 7930a7d1d5cSxiaofeibao blockedByWaitForward(0) := !io.enqRob.isEmpty && isWaitForward(0) 7940a7d1d5cSxiaofeibao for (i <- 1 until RenameWidth) { 7950a7d1d5cSxiaofeibao blockedByWaitForward(i) := blockedByWaitForward(i - 1) || (!io.enqRob.isEmpty || Cat(fromRename.take(i).map(_.valid)).orR) && isWaitForward(i) 7960a7d1d5cSxiaofeibao } 7970a7d1d5cSxiaofeibao if(backendParams.debugEn){ 7980a7d1d5cSxiaofeibao dontTouch(blockedByWaitForward) 7994e7f9e52Sxiaofeibao dontTouch(conserveFlows) 8000a7d1d5cSxiaofeibao } 8010a7d1d5cSxiaofeibao 8020a7d1d5cSxiaofeibao // Only the uop with block backward flag will block the next uop 8030a7d1d5cSxiaofeibao val nextCanOut = VecInit((0 until RenameWidth).map(i => 8040a7d1d5cSxiaofeibao !isBlockBackward(i) 8050a7d1d5cSxiaofeibao )) 8060a7d1d5cSxiaofeibao val notBlockedByPrevious = VecInit((0 until RenameWidth).map(i => 8070a7d1d5cSxiaofeibao if (i == 0) true.B 8080a7d1d5cSxiaofeibao else Cat((0 until i).map(j => nextCanOut(j))).andR 8090a7d1d5cSxiaofeibao )) 8100a7d1d5cSxiaofeibao 8110a7d1d5cSxiaofeibao // for noSpecExec: (robEmpty || !this.noSpecExec) && !previous.noSpecExec 8120a7d1d5cSxiaofeibao // For blockBackward: 8130a7d1d5cSxiaofeibao // this instruction can actually dequeue: 3 conditions 8140a7d1d5cSxiaofeibao // (1) resources are ready 8150a7d1d5cSxiaofeibao // (2) previous instructions are ready 8160a7d1d5cSxiaofeibao thisCanActualOut := VecInit((0 until RenameWidth).map(i => !blockedByWaitForward(i) && notBlockedByPrevious(i) && io.enqRob.canAccept)) 8170a7d1d5cSxiaofeibao val thisActualOut = (0 until RenameWidth).map(i => io.enqRob.req(i).valid && io.enqRob.canAccept) 8180a7d1d5cSxiaofeibao 8190a7d1d5cSxiaofeibao // input for ROB, LSQ 8200a7d1d5cSxiaofeibao for (i <- 0 until RenameWidth) { 8210a7d1d5cSxiaofeibao // needAlloc no use, need deleted 8220a7d1d5cSxiaofeibao io.enqRob.needAlloc(i) := fromRename(i).valid 8230a7d1d5cSxiaofeibao io.enqRob.req(i).valid := fromRename(i).fire 8240a7d1d5cSxiaofeibao io.enqRob.req(i).bits := updatedUop(i) 8250a7d1d5cSxiaofeibao io.enqRob.req(i).bits.hasException := updatedUop(i).hasException || updatedUop(i).singleStep 8260a7d1d5cSxiaofeibao io.enqRob.req(i).bits.numWB := Mux(updatedUop(i).singleStep, 0.U, updatedUop(i).numWB) 8270a7d1d5cSxiaofeibao } 8280a7d1d5cSxiaofeibao 8290a7d1d5cSxiaofeibao val hasValidInstr = VecInit(fromRename.map(_.valid)).asUInt.orR 8300a7d1d5cSxiaofeibao val hasSpecialInstr = Cat((0 until RenameWidth).map(i => isBlockBackward(i))).orR 8310a7d1d5cSxiaofeibao 8320a7d1d5cSxiaofeibao private val canAccept = !hasValidInstr || !hasSpecialInstr && io.enqRob.canAccept 8330a7d1d5cSxiaofeibao 8340a7d1d5cSxiaofeibao val isWaitForwardOrBlockBackward = isWaitForward.asUInt.orR || isBlockBackward.asUInt.orR 8350a7d1d5cSxiaofeibao val renameFireCnt = PopCount(fromRename.map(_.fire)) 8360a7d1d5cSxiaofeibao 8370a7d1d5cSxiaofeibao val stall_rob = hasValidInstr && !io.enqRob.canAccept 8380a7d1d5cSxiaofeibao val stall_int_dq = hasValidInstr && io.enqRob.canAccept 8390a7d1d5cSxiaofeibao val stall_int_dq0 = hasValidInstr && io.enqRob.canAccept 8400a7d1d5cSxiaofeibao val stall_int_dq1 = hasValidInstr && io.enqRob.canAccept 8410a7d1d5cSxiaofeibao val stall_fp_dq = hasValidInstr && io.enqRob.canAccept 8420a7d1d5cSxiaofeibao val stall_ls_dq = hasValidInstr && io.enqRob.canAccept 8430a7d1d5cSxiaofeibao 8440a7d1d5cSxiaofeibao XSPerfAccumulate("in_valid_count", PopCount(fromRename.map(_.valid))) 8450a7d1d5cSxiaofeibao XSPerfAccumulate("in_fire_count", PopCount(fromRename.map(_.fire))) 8460a7d1d5cSxiaofeibao XSPerfAccumulate("in_valid_not_ready_count", PopCount(fromRename.map(x => x.valid && !x.ready))) 8470a7d1d5cSxiaofeibao XSPerfAccumulate("wait_cycle", !fromRename.head.valid && allResourceReady) 8480a7d1d5cSxiaofeibao 8490a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_rob", stall_rob) 8500a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_int_dq0", stall_int_dq0) 8510a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_int_dq1", stall_int_dq1) 8520a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_fp_dq", stall_fp_dq) 8530a7d1d5cSxiaofeibao XSPerfAccumulate("stall_cycle_ls_dq", stall_ls_dq) 8540a7d1d5cSxiaofeibao 8550a7d1d5cSxiaofeibao val notIssue = !io.debugTopDown.fromRob.robHeadLsIssue 8560a7d1d5cSxiaofeibao val tlbReplay = io.debugTopDown.fromCore.fromMem.robHeadTlbReplay 8570a7d1d5cSxiaofeibao val tlbMiss = io.debugTopDown.fromCore.fromMem.robHeadTlbMiss 8580a7d1d5cSxiaofeibao val vioReplay = io.debugTopDown.fromCore.fromMem.robHeadLoadVio 8590a7d1d5cSxiaofeibao val mshrReplay = io.debugTopDown.fromCore.fromMem.robHeadLoadMSHR 8600a7d1d5cSxiaofeibao val l1Miss = io.debugTopDown.fromCore.fromMem.robHeadMissInDCache 8610a7d1d5cSxiaofeibao val l2Miss = io.debugTopDown.fromCore.l2MissMatch 8620a7d1d5cSxiaofeibao val l3Miss = io.debugTopDown.fromCore.l3MissMatch 8630a7d1d5cSxiaofeibao 8640a7d1d5cSxiaofeibao val ldReason = Mux(l3Miss, TopDownCounters.LoadMemStall.id.U, 8650a7d1d5cSxiaofeibao Mux(l2Miss, TopDownCounters.LoadL3Stall.id.U, 8660a7d1d5cSxiaofeibao Mux(l1Miss, TopDownCounters.LoadL2Stall.id.U, 8670a7d1d5cSxiaofeibao Mux(notIssue, TopDownCounters.MemNotReadyStall.id.U, 8680a7d1d5cSxiaofeibao Mux(tlbMiss, TopDownCounters.LoadTLBStall.id.U, 8690a7d1d5cSxiaofeibao Mux(tlbReplay, TopDownCounters.LoadTLBStall.id.U, 8700a7d1d5cSxiaofeibao Mux(mshrReplay, TopDownCounters.LoadMSHRReplayStall.id.U, 8710a7d1d5cSxiaofeibao Mux(vioReplay, TopDownCounters.LoadVioReplayStall.id.U, 8720a7d1d5cSxiaofeibao TopDownCounters.LoadL1Stall.id.U)))))))) 8730a7d1d5cSxiaofeibao 874*f9daee66SZifei Zhang val fusedVec = (0 until RenameWidth).map{ case i => 875*f9daee66SZifei Zhang if (i == 0) false.B 876*f9daee66SZifei Zhang else (io.fromRename(i-1).fire && !io.fromRename(i).valid && 877*f9daee66SZifei Zhang CommitType.isFused(io.fromRename(i-1).bits.commitType)) 878*f9daee66SZifei Zhang } 879*f9daee66SZifei Zhang 8800a7d1d5cSxiaofeibao val decodeReason = RegNextN(io.stallReason.reason, 2) 8810a7d1d5cSxiaofeibao val renameReason = RegNext(io.stallReason.reason) 8820a7d1d5cSxiaofeibao 8830a7d1d5cSxiaofeibao val stallReason = Wire(chiselTypeOf(io.stallReason.reason)) 8840a7d1d5cSxiaofeibao val firedVec = fromRename.map(_.fire) 8850a7d1d5cSxiaofeibao io.stallReason.backReason.valid := !canAccept 8860a7d1d5cSxiaofeibao io.stallReason.backReason.bits := TopDownCounters.OtherCoreStall.id.U 887*f9daee66SZifei Zhang stallReason.zip(io.stallReason.reason).zip(firedVec).zipWithIndex.zip(fusedVec).map { case ((((update, in), fire), idx), fused) => 8880a7d1d5cSxiaofeibao val headIsInt = FuType.isInt(io.robHead.getDebugFuType) && io.robHeadNotReady 8890a7d1d5cSxiaofeibao val headIsFp = FuType.isFArith(io.robHead.getDebugFuType) && io.robHeadNotReady 8900a7d1d5cSxiaofeibao val headIsDiv = FuType.isDivSqrt(io.robHead.getDebugFuType) && io.robHeadNotReady 8910a7d1d5cSxiaofeibao val headIsLd = io.robHead.getDebugFuType === FuType.ldu.U && io.robHeadNotReady || !io.lqCanAccept 8920a7d1d5cSxiaofeibao val headIsSt = io.robHead.getDebugFuType === FuType.stu.U && io.robHeadNotReady || !io.sqCanAccept 8930a7d1d5cSxiaofeibao val headIsAmo = io.robHead.getDebugFuType === FuType.mou.U && io.robHeadNotReady 8940a7d1d5cSxiaofeibao val headIsLs = headIsLd || headIsSt 8950a7d1d5cSxiaofeibao val robLsFull = io.robFull || !io.lqCanAccept || !io.sqCanAccept 8960a7d1d5cSxiaofeibao 8970a7d1d5cSxiaofeibao import TopDownCounters._ 8980a7d1d5cSxiaofeibao update := MuxCase(OtherCoreStall.id.U, Seq( 8990a7d1d5cSxiaofeibao // fire 900*f9daee66SZifei Zhang (fire || fused ) -> NoStall.id.U , 9010a7d1d5cSxiaofeibao // dispatch not stall / core stall from decode or rename 9020a7d1d5cSxiaofeibao (in =/= OtherCoreStall.id.U && in =/= NoStall.id.U ) -> in , 9030a7d1d5cSxiaofeibao // rob stall 9040a7d1d5cSxiaofeibao (headIsAmo ) -> AtomicStall.id.U , 9050a7d1d5cSxiaofeibao (headIsSt ) -> StoreStall.id.U , 9060a7d1d5cSxiaofeibao (headIsLd ) -> ldReason , 9070a7d1d5cSxiaofeibao (headIsDiv ) -> DivStall.id.U , 9080a7d1d5cSxiaofeibao (headIsInt ) -> IntNotReadyStall.id.U , 9090a7d1d5cSxiaofeibao (headIsFp ) -> FPNotReadyStall.id.U , 9100a7d1d5cSxiaofeibao (renameReason(idx) =/= NoStall.id.U ) -> renameReason(idx) , 9110a7d1d5cSxiaofeibao (decodeReason(idx) =/= NoStall.id.U ) -> decodeReason(idx) , 9120a7d1d5cSxiaofeibao )) 9130a7d1d5cSxiaofeibao } 9140a7d1d5cSxiaofeibao 915ef7a7f80STang Haojin TopDownCounters.values.foreach(ctr => XSPerfAccumulate(ctr.toString(), PopCount(stallReason.map(_ === ctr.id.U)), XSPerfLevel.CRITICAL)) 9160a7d1d5cSxiaofeibao 9170a7d1d5cSxiaofeibao val robTrueCommit = io.debugTopDown.fromRob.robTrueCommit 9180a7d1d5cSxiaofeibao TopDownCounters.values.foreach(ctr => XSPerfRolling("td_"+ctr.toString(), PopCount(stallReason.map(_ === ctr.id.U)), 9190a7d1d5cSxiaofeibao robTrueCommit, 1000, clock, reset)) 9200a7d1d5cSxiaofeibao 9210a7d1d5cSxiaofeibao XSPerfHistogram("slots_fire", PopCount(thisActualOut), true.B, 0, RenameWidth+1, 1) 9220a7d1d5cSxiaofeibao // Explaination: when out(0) not fire, PopCount(valid) is not meaningfull 9230a7d1d5cSxiaofeibao XSPerfHistogram("slots_valid_pure", PopCount(io.enqRob.req.map(_.valid)), thisActualOut(0), 0, RenameWidth+1, 1) 9240a7d1d5cSxiaofeibao XSPerfHistogram("slots_valid_rough", PopCount(io.enqRob.req.map(_.valid)), true.B, 0, RenameWidth+1, 1) 9250a7d1d5cSxiaofeibao 9260a7d1d5cSxiaofeibao val perfEvents = Seq( 9270a7d1d5cSxiaofeibao ("dispatch_in", PopCount(fromRename.map(_.valid && fromRename(0).ready)) ), 9280a7d1d5cSxiaofeibao ("dispatch_empty", !hasValidInstr ), 9290a7d1d5cSxiaofeibao ("dispatch_utili", PopCount(fromRename.map(_.valid)) ), 9300a7d1d5cSxiaofeibao ("dispatch_waitinstr", PopCount(fromRename.map(!_.valid && canAccept)) ), 9310a7d1d5cSxiaofeibao ("dispatch_stall_cycle_lsq", false.B ), 9320a7d1d5cSxiaofeibao ("dispatch_stall_cycle_rob", stall_rob ), 9330a7d1d5cSxiaofeibao ("dispatch_stall_cycle_int_dq", stall_int_dq ), 9340a7d1d5cSxiaofeibao ("dispatch_stall_cycle_fp_dq", stall_fp_dq ), 9350a7d1d5cSxiaofeibao ("dispatch_stall_cycle_ls_dq", stall_ls_dq ) 9360a7d1d5cSxiaofeibao ) 9370a7d1d5cSxiaofeibao generatePerfEvent() 9380a7d1d5cSxiaofeibao} 939