1730cfbc0SXuan Hupackage xiangshan.backend.issue 2730cfbc0SXuan Hu 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 4730cfbc0SXuan Huimport chisel3._ 55d2b9cadSXuan Huimport chisel3.util._ 6bf35baadSXuan Huimport utils.SeqUtils 7dd473fffSXuan Huimport xiangshan.backend.BackendParams 85d2b9cadSXuan Huimport xiangshan.backend.Bundles._ 939c59369SXuan Huimport xiangshan.backend.datapath.DataConfig.DataConfig 1039c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.PregWB 115d2b9cadSXuan Huimport xiangshan.backend.datapath.{WakeUpConfig, WakeUpSource} 1239c59369SXuan Huimport xiangshan.backend.exu.{ExeUnit, ExeUnitParams} 135d2b9cadSXuan Huimport xiangshan.backend.fu.{FuConfig, FuType} 14730cfbc0SXuan Hu 15730cfbc0SXuan Hucase class IssueBlockParams( 16730cfbc0SXuan Hu // top down 17730cfbc0SXuan Hu exuBlockParams : Seq[ExeUnitParams], 18730cfbc0SXuan Hu numEntries : Int, 19bf35baadSXuan Hu numEnq : Int, 20730cfbc0SXuan Hu numDeqOutside : Int = 0, 21730cfbc0SXuan Hu numWakeupFromOthers: Int = 0, 22730cfbc0SXuan Hu XLEN : Int = 64, 23730cfbc0SXuan Hu VLEN : Int = 128, 24730cfbc0SXuan Hu vaddrBits : Int = 39, 25730cfbc0SXuan Hu // calculate in scheduler 269b258a00Sxgkiri var idxInSchBlk : Int = 0, 27730cfbc0SXuan Hu)( 28730cfbc0SXuan Hu implicit 29730cfbc0SXuan Hu val schdType: SchedulerType, 30730cfbc0SXuan Hu) { 31dd473fffSXuan Hu var backendParam: BackendParams = null 32dd473fffSXuan Hu 339b258a00Sxgkiri def updateIdx(idx: Int): Unit = { 349b258a00Sxgkiri this.idxInSchBlk = idx 359b258a00Sxgkiri } 369b258a00Sxgkiri 37730cfbc0SXuan Hu def inMemSchd: Boolean = schdType == MemScheduler() 38730cfbc0SXuan Hu 39730cfbc0SXuan Hu def inIntSchd: Boolean = schdType == IntScheduler() 40730cfbc0SXuan Hu 41730cfbc0SXuan Hu def inVfSchd: Boolean = schdType == VfScheduler() 42730cfbc0SXuan Hu 43730cfbc0SXuan Hu def isMemAddrIQ: Boolean = inMemSchd && StdCnt == 0 44730cfbc0SXuan Hu 45730cfbc0SXuan Hu def isLdAddrIQ: Boolean = inMemSchd && LduCnt > 0 46730cfbc0SXuan Hu 47730cfbc0SXuan Hu def isStAddrIQ: Boolean = inMemSchd && StaCnt > 0 48730cfbc0SXuan Hu 49730cfbc0SXuan Hu def numExu: Int = exuBlockParams.length 50730cfbc0SXuan Hu 51730cfbc0SXuan Hu def numIntSrc: Int = exuBlockParams.map(_.numIntSrc).max 52730cfbc0SXuan Hu 53730cfbc0SXuan Hu def numFpSrc: Int = exuBlockParams.map(_.numFpSrc).max 54730cfbc0SXuan Hu 55730cfbc0SXuan Hu def numVecSrc: Int = exuBlockParams.map(_.numVecSrc).max 56730cfbc0SXuan Hu 57730cfbc0SXuan Hu def numVfSrc: Int = exuBlockParams.map(_.numVfSrc).max 58730cfbc0SXuan Hu 59730cfbc0SXuan Hu def numRegSrc: Int = exuBlockParams.map(_.numRegSrc).max 60730cfbc0SXuan Hu 61730cfbc0SXuan Hu def numSrc: Int = exuBlockParams.map(_.numSrc).max 62730cfbc0SXuan Hu 63730cfbc0SXuan Hu def readIntRf: Boolean = numIntSrc > 0 64730cfbc0SXuan Hu 65730cfbc0SXuan Hu def readFpRf: Boolean = numFpSrc > 0 66730cfbc0SXuan Hu 67730cfbc0SXuan Hu def readVecRf: Boolean = numVecSrc > 0 68730cfbc0SXuan Hu 69730cfbc0SXuan Hu def readVfRf: Boolean = numVfSrc > 0 70730cfbc0SXuan Hu 71730cfbc0SXuan Hu def writeIntRf: Boolean = exuBlockParams.map(_.writeIntRf).reduce(_ || _) 72730cfbc0SXuan Hu 73730cfbc0SXuan Hu def writeFpRf: Boolean = exuBlockParams.map(_.writeFpRf).reduce(_ || _) 74730cfbc0SXuan Hu 75730cfbc0SXuan Hu def writeVecRf: Boolean = exuBlockParams.map(_.writeVecRf).reduce(_ || _) 76730cfbc0SXuan Hu 77730cfbc0SXuan Hu def exceptionOut: Seq[Int] = exuBlockParams.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted 78730cfbc0SXuan Hu 79730cfbc0SXuan Hu def hasLoadError: Boolean = exuBlockParams.map(_.hasLoadError).reduce(_ || _) 80730cfbc0SXuan Hu 81730cfbc0SXuan Hu def flushPipe: Boolean = exuBlockParams.map(_.flushPipe).reduce(_ || _) 82730cfbc0SXuan Hu 83730cfbc0SXuan Hu def replayInst: Boolean = exuBlockParams.map(_.replayInst).reduce(_ || _) 84730cfbc0SXuan Hu 85730cfbc0SXuan Hu def trigger: Boolean = exuBlockParams.map(_.trigger).reduce(_ || _) 86730cfbc0SXuan Hu 87730cfbc0SXuan Hu def needExceptionGen: Boolean = exceptionOut.nonEmpty || flushPipe || replayInst || trigger 88730cfbc0SXuan Hu 89730cfbc0SXuan Hu def needPc: Boolean = JmpCnt + BrhCnt + FenceCnt > 0 90730cfbc0SXuan Hu 91730cfbc0SXuan Hu def needSrcFrm: Boolean = exuBlockParams.map(_.needSrcFrm).reduce(_ || _) 92730cfbc0SXuan Hu 93730cfbc0SXuan Hu def numPcReadPort: Int = (if (needPc) 1 else 0) * numEnq 94730cfbc0SXuan Hu 95730cfbc0SXuan Hu def numWriteIntRf: Int = exuBlockParams.count(_.writeIntRf) 96730cfbc0SXuan Hu 97730cfbc0SXuan Hu def numWriteFpRf: Int = exuBlockParams.count(_.writeFpRf) 98730cfbc0SXuan Hu 99730cfbc0SXuan Hu def numWriteVecRf: Int = exuBlockParams.count(_.writeVecRf) 100730cfbc0SXuan Hu 101730cfbc0SXuan Hu def numWriteVfRf: Int = exuBlockParams.count(_.writeVfRf) 102730cfbc0SXuan Hu 103730cfbc0SXuan Hu def numNoDataWB: Int = exuBlockParams.count(_.hasNoDataWB) 104730cfbc0SXuan Hu 105730cfbc0SXuan Hu def dataBitsMax: Int = if (numVecSrc > 0) VLEN else XLEN 106730cfbc0SXuan Hu 107730cfbc0SXuan Hu def numDeq: Int = numDeqOutside + exuBlockParams.length 108730cfbc0SXuan Hu 109730cfbc0SXuan Hu def JmpCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.jmp)).sum 110730cfbc0SXuan Hu 111730cfbc0SXuan Hu def BrhCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.brh)).sum 112730cfbc0SXuan Hu 113730cfbc0SXuan Hu def I2fCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.i2f)).sum 114730cfbc0SXuan Hu 115730cfbc0SXuan Hu def CsrCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.csr)).sum 116730cfbc0SXuan Hu 117730cfbc0SXuan Hu def AluCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.alu)).sum 118730cfbc0SXuan Hu 119730cfbc0SXuan Hu def MulCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.mul)).sum 120730cfbc0SXuan Hu 121730cfbc0SXuan Hu def DivCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.div)).sum 122730cfbc0SXuan Hu 123730cfbc0SXuan Hu def FenceCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fence)).sum 124730cfbc0SXuan Hu 125730cfbc0SXuan Hu def BkuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.bku)).sum 126730cfbc0SXuan Hu 127d91483a6Sfdy def VsetCnt: Int = exuBlockParams.map(_.fuConfigs.count(x => x.fuType == FuType.vsetiwi || x.fuType == FuType.vsetiwf || x.fuType == FuType.vsetfwf)).sum 128730cfbc0SXuan Hu 129730cfbc0SXuan Hu def FmacCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fmac)).sum 130730cfbc0SXuan Hu 131730cfbc0SXuan Hu def FmiscCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fmisc)).sum 132730cfbc0SXuan Hu 133730cfbc0SXuan Hu def fDivSqrtCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fDivSqrt)).sum 134730cfbc0SXuan Hu 135*b133b458SXuan Hu def LduCnt: Int = exuBlockParams.count(x => x.hasLoadFu && !x.hasStoreAddrFu) 136730cfbc0SXuan Hu 137*b133b458SXuan Hu def StaCnt: Int = exuBlockParams.count(x => !x.hasLoadFu && x.hasStoreAddrFu) 138730cfbc0SXuan Hu 139730cfbc0SXuan Hu def MouCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.mou)).sum 140730cfbc0SXuan Hu 141730cfbc0SXuan Hu def StdCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.name == "std")).sum 142730cfbc0SXuan Hu 143*b133b458SXuan Hu def HyuCnt: Int = exuBlockParams.count(_.hasHybridAddrFu) 144*b133b458SXuan Hu 145730cfbc0SXuan Hu def VipuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vipu)).sum 146730cfbc0SXuan Hu 147730cfbc0SXuan Hu def VfpuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vfpu)).sum 148730cfbc0SXuan Hu 149730cfbc0SXuan Hu def VlduCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vldu)).sum 150730cfbc0SXuan Hu 151730cfbc0SXuan Hu def VstuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vstu)).sum 152730cfbc0SXuan Hu 153730cfbc0SXuan Hu def numRedirect: Int = exuBlockParams.count(_.hasRedirect) 154730cfbc0SXuan Hu 15539c59369SXuan Hu /** 15639c59369SXuan Hu * Get the regfile type that this issue queue need to read 15739c59369SXuan Hu */ 15839c59369SXuan Hu def pregReadSet: Set[DataConfig] = exuBlockParams.map(_.pregRdDataCfgSet).fold(Set())(_ union _) 15939c59369SXuan Hu 16039c59369SXuan Hu /** 16139c59369SXuan Hu * Get the regfile type that this issue queue need to read 16239c59369SXuan Hu */ 16339c59369SXuan Hu def pregWriteSet: Set[DataConfig] = exuBlockParams.map(_.pregWbDataCfgSet).fold(Set())(_ union _) 16439c59369SXuan Hu 16539c59369SXuan Hu /** 16639c59369SXuan Hu * Get the max width of psrc 16739c59369SXuan Hu */ 16839c59369SXuan Hu def rdPregIdxWidth = { 16939c59369SXuan Hu this.pregReadSet.map(cfg => backendParam.getPregParams(cfg).addrWidth).fold(0)(_ max _) 17039c59369SXuan Hu } 17139c59369SXuan Hu 17239c59369SXuan Hu /** 17339c59369SXuan Hu * Get the max width of pdest 17439c59369SXuan Hu */ 17539c59369SXuan Hu def wbPregIdxWidth = { 17639c59369SXuan Hu this.pregWriteSet.map(cfg => backendParam.getPregParams(cfg).addrWidth).fold(0)(_ max _) 17739c59369SXuan Hu } 17839c59369SXuan Hu 179bf35baadSXuan Hu def iqWakeUpSourcePairs: Seq[WakeUpConfig] = exuBlockParams.flatMap(_.iqWakeUpSourcePairs) 180bf35baadSXuan Hu 181bf35baadSXuan Hu /** Get exu source wake up 182bf35baadSXuan Hu * @todo replace with 183bf35baadSXuan Hu * exuBlockParams 184bf35baadSXuan Hu * .flatMap(_.iqWakeUpSinkPairs) 185bf35baadSXuan Hu * .map(_.source) 186bf35baadSXuan Hu * .distinctBy(_.name) 187bf35baadSXuan Hu * when xiangshan is updated to 2.13.11 188bf35baadSXuan Hu */ 189bf35baadSXuan Hu def wakeUpInExuSources: Seq[WakeUpSource] = { 190bf35baadSXuan Hu SeqUtils.distinctBy( 191bf35baadSXuan Hu exuBlockParams 192bf35baadSXuan Hu .flatMap(_.iqWakeUpSinkPairs) 193bf35baadSXuan Hu .map(_.source) 194bf35baadSXuan Hu )(_.name) 195bf35baadSXuan Hu } 196bf35baadSXuan Hu 197bf35baadSXuan Hu def wakeUpOutExuSources: Seq[WakeUpSource] = { 198bf35baadSXuan Hu SeqUtils.distinctBy( 199bf35baadSXuan Hu exuBlockParams 200bf35baadSXuan Hu .flatMap(_.iqWakeUpSourcePairs) 201bf35baadSXuan Hu .map(_.source) 202bf35baadSXuan Hu )(_.name) 203bf35baadSXuan Hu } 204bf35baadSXuan Hu 205bf35baadSXuan Hu def wakeUpToExuSinks = exuBlockParams 206bf35baadSXuan Hu .flatMap(_.iqWakeUpSourcePairs) 207bf35baadSXuan Hu .map(_.sink).distinct 208bf35baadSXuan Hu 209bf35baadSXuan Hu def numWakeupFromIQ: Int = wakeUpInExuSources.size 210bf35baadSXuan Hu 211bf35baadSXuan Hu def numAllWakeUp: Int = numWakeupFromWB + numWakeupFromIQ + numWakeupFromOthers 212730cfbc0SXuan Hu 21339c59369SXuan Hu def numWakeupFromWB = { 21439c59369SXuan Hu val pregSet = this.pregReadSet 21539c59369SXuan Hu pregSet.map(cfg => backendParam.getRfWriteSize(cfg)).sum 21639c59369SXuan Hu } 21739c59369SXuan Hu 218c0be7f33SXuan Hu def hasIQWakeUp: Boolean = numWakeupFromIQ > 0 219c0be7f33SXuan Hu 220730cfbc0SXuan Hu def getFuCfgs: Seq[FuConfig] = exuBlockParams.flatMap(_.fuConfigs).distinct 221730cfbc0SXuan Hu 222730cfbc0SXuan Hu // cfgs(exuIdx)(set of exu's wb) 22339c59369SXuan Hu 22439c59369SXuan Hu /** 22539c59369SXuan Hu * Get [[PregWB]] of this IssueBlock 22639c59369SXuan Hu * @return set of [[PregWB]] of [[ExeUnit]] 22739c59369SXuan Hu */ 22839c59369SXuan Hu def getWbCfgs: Seq[Set[PregWB]] = { 229730cfbc0SXuan Hu exuBlockParams.map(exu => exu.wbPortConfigs.toSet) 230730cfbc0SXuan Hu } 231730cfbc0SXuan Hu 232730cfbc0SXuan Hu def canAccept(fuType: UInt): Bool = { 233730cfbc0SXuan Hu Cat(getFuCfgs.map(_.fuType.U === fuType)).orR 234730cfbc0SXuan Hu } 235730cfbc0SXuan Hu 236dd473fffSXuan Hu def bindBackendParam(param: BackendParams): Unit = { 237dd473fffSXuan Hu backendParam = param 238dd473fffSXuan Hu } 239dd473fffSXuan Hu 240730cfbc0SXuan Hu def genExuInputDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[ExuInput]] = { 241730cfbc0SXuan Hu MixedVec(this.exuBlockParams.map(x => DecoupledIO(x.genExuInputBundle))) 242730cfbc0SXuan Hu } 243730cfbc0SXuan Hu 244730cfbc0SXuan Hu def genExuOutputDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[ExuOutput]] = { 245730cfbc0SXuan Hu MixedVec(this.exuBlockParams.map(x => DecoupledIO(x.genExuOutputBundle))) 246730cfbc0SXuan Hu } 247730cfbc0SXuan Hu 248730cfbc0SXuan Hu def genExuOutputValidBundle(implicit p: Parameters): MixedVec[ValidIO[ExuOutput]] = { 249730cfbc0SXuan Hu MixedVec(this.exuBlockParams.map(x => ValidIO(x.genExuOutputBundle))) 250730cfbc0SXuan Hu } 251730cfbc0SXuan Hu 2525d2b9cadSXuan Hu def genExuBypassValidBundle(implicit p: Parameters): MixedVec[ValidIO[ExuBypassBundle]] = { 2535d2b9cadSXuan Hu MixedVec(this.exuBlockParams.map(x => ValidIO(x.genExuBypassBundle))) 2545d2b9cadSXuan Hu } 2555d2b9cadSXuan Hu 256730cfbc0SXuan Hu def genIssueDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[IssueQueueIssueBundle]] = { 25739c59369SXuan Hu MixedVec(exuBlockParams.map(x => DecoupledIO(new IssueQueueIssueBundle(this, x)))) 258730cfbc0SXuan Hu } 259730cfbc0SXuan Hu 260c0be7f33SXuan Hu def genWBWakeUpSinkValidBundle: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = { 261c0be7f33SXuan Hu val intBundle: Seq[ValidIO[IssueQueueWBWakeUpBundle]] = schdType match { 262c0be7f33SXuan Hu case IntScheduler() | MemScheduler() => backendParam.getIntWBExeGroup.map(x => ValidIO(new IssueQueueWBWakeUpBundle(x._2.map(_.exuIdx), backendParam))).toSeq 263c0be7f33SXuan Hu case _ => Seq() 264c0be7f33SXuan Hu } 265c0be7f33SXuan Hu val vfBundle = schdType match { 266c0be7f33SXuan Hu case VfScheduler() | MemScheduler() => backendParam.getVfWBExeGroup.map(x => ValidIO(new IssueQueueWBWakeUpBundle(x._2.map(_.exuIdx), backendParam))).toSeq 267c0be7f33SXuan Hu case _ => Seq() 268c0be7f33SXuan Hu } 269c0be7f33SXuan Hu MixedVec(intBundle ++ vfBundle) 270bf35baadSXuan Hu } 271bf35baadSXuan Hu 272c0be7f33SXuan Hu def genIQWakeUpSourceValidBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = { 273c0be7f33SXuan Hu MixedVec(exuBlockParams.map(x => ValidIO(new IssueQueueIQWakeUpBundle(x.exuIdx, backendParam)))) 274c0be7f33SXuan Hu } 275c0be7f33SXuan Hu 276c0be7f33SXuan Hu def genIQWakeUpSinkValidBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = { 277c0be7f33SXuan Hu MixedVec(this.wakeUpInExuSources.map(x => ValidIO(new IssueQueueIQWakeUpBundle(backendParam.getExuIdx(x.name), backendParam)))) 278c0be7f33SXuan Hu } 279c0be7f33SXuan Hu 280730cfbc0SXuan Hu def genOGRespBundle(implicit p: Parameters) = { 281730cfbc0SXuan Hu implicit val issueBlockParams = this 282730cfbc0SXuan Hu MixedVec(exuBlockParams.map(_ => new OGRespBundle)) 283730cfbc0SXuan Hu } 284730cfbc0SXuan Hu 285dd970561SzhanglyGit def genWbFuBusyTableWriteBundle()(implicit p: Parameters) = { 2868d29ec32Sczw implicit val issueBlockParams = this 287dd970561SzhanglyGit MixedVec(exuBlockParams.map(x => new WbFuBusyTableWriteBundle(x))) 2888d29ec32Sczw } 2898d29ec32Sczw 2902e0a7dc5Sfdy def genWbFuBusyTableReadBundle()(implicit p: Parameters) = { 2918d29ec32Sczw implicit val issueBlockParams = this 2922e0a7dc5Sfdy MixedVec(exuBlockParams.map{ x => 2932e0a7dc5Sfdy new WbFuBusyTableReadBundle(x) 2942e0a7dc5Sfdy }) 2952e0a7dc5Sfdy } 2962e0a7dc5Sfdy 2972e0a7dc5Sfdy def genWbConflictBundle()(implicit p: Parameters) = { 2982e0a7dc5Sfdy implicit val issueBlockParams = this 2992e0a7dc5Sfdy MixedVec(exuBlockParams.map { x => 3002e0a7dc5Sfdy new WbConflictBundle(x) 3012e0a7dc5Sfdy }) 3028d29ec32Sczw } 3038d29ec32Sczw 304730cfbc0SXuan Hu def getIQName = { 305730cfbc0SXuan Hu "IssueQueue" ++ getFuCfgs.map(_.name).distinct.map(_.capitalize).reduce(_ ++ _) 306730cfbc0SXuan Hu } 307730cfbc0SXuan Hu} 308