1package xiangshan.backend.issue 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3.util._ 5import chisel3._ 6import xiangshan.backend.Bundles.{ExuInput, ExuOutput, IssueQueueIssueBundle, IssueQueueWakeUpBundle, OGRespBundle, WbConflictBundle, WbFuBusyTableReadBundle, WbFuBusyTableWriteBundle} 7import xiangshan.backend.datapath.{WakeUpConfig, WakeUpSource} 8import xiangshan.backend.datapath.WbConfig.WbConfig 9import xiangshan.backend.exu.ExeUnitParams 10import xiangshan.backend.fu.{FuConfig, FuType} 11import utils.SeqUtils 12import xiangshan.backend.BackendParams 13 14case class IssueBlockParams( 15 // top down 16 exuBlockParams : Seq[ExeUnitParams], 17 numEntries : Int, 18 pregBits : Int, 19 numWakeupFromWB : Int, 20 numEnq : Int, 21 numDeqOutside : Int = 0, 22 numWakeupFromOthers: Int = 0, 23 XLEN : Int = 64, 24 VLEN : Int = 128, 25 vaddrBits : Int = 39, 26 // calculate in scheduler 27 var idxInSchBlk : Int = 0, 28)( 29 implicit 30 val schdType: SchedulerType, 31) { 32 var backendParam: BackendParams = null 33 34 def updateIdx(idx: Int): Unit = { 35 this.idxInSchBlk = idx 36 } 37 38 def inMemSchd: Boolean = schdType == MemScheduler() 39 40 def inIntSchd: Boolean = schdType == IntScheduler() 41 42 def inVfSchd: Boolean = schdType == VfScheduler() 43 44 def isMemAddrIQ: Boolean = inMemSchd && StdCnt == 0 45 46 def isLdAddrIQ: Boolean = inMemSchd && LduCnt > 0 47 48 def isStAddrIQ: Boolean = inMemSchd && StaCnt > 0 49 50 def numExu: Int = exuBlockParams.length 51 52 def numIntSrc: Int = exuBlockParams.map(_.numIntSrc).max 53 54 def numFpSrc: Int = exuBlockParams.map(_.numFpSrc).max 55 56 def numVecSrc: Int = exuBlockParams.map(_.numVecSrc).max 57 58 def numVfSrc: Int = exuBlockParams.map(_.numVfSrc).max 59 60 def numRegSrc: Int = exuBlockParams.map(_.numRegSrc).max 61 62 def numSrc: Int = exuBlockParams.map(_.numSrc).max 63 64 def readIntRf: Boolean = numIntSrc > 0 65 66 def readFpRf: Boolean = numFpSrc > 0 67 68 def readVecRf: Boolean = numVecSrc > 0 69 70 def readVfRf: Boolean = numVfSrc > 0 71 72 def writeIntRf: Boolean = exuBlockParams.map(_.writeIntRf).reduce(_ || _) 73 74 def writeFpRf: Boolean = exuBlockParams.map(_.writeFpRf).reduce(_ || _) 75 76 def writeVecRf: Boolean = exuBlockParams.map(_.writeVecRf).reduce(_ || _) 77 78 def exceptionOut: Seq[Int] = exuBlockParams.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted 79 80 def hasLoadError: Boolean = exuBlockParams.map(_.hasLoadError).reduce(_ || _) 81 82 def flushPipe: Boolean = exuBlockParams.map(_.flushPipe).reduce(_ || _) 83 84 def replayInst: Boolean = exuBlockParams.map(_.replayInst).reduce(_ || _) 85 86 def trigger: Boolean = exuBlockParams.map(_.trigger).reduce(_ || _) 87 88 def needExceptionGen: Boolean = exceptionOut.nonEmpty || flushPipe || replayInst || trigger 89 90 def needPc: Boolean = JmpCnt + BrhCnt + FenceCnt > 0 91 92 def needSrcFrm: Boolean = exuBlockParams.map(_.needSrcFrm).reduce(_ || _) 93 94 def numPcReadPort: Int = (if (needPc) 1 else 0) * numEnq 95 96 def numWriteIntRf: Int = exuBlockParams.count(_.writeIntRf) 97 98 def numWriteFpRf: Int = exuBlockParams.count(_.writeFpRf) 99 100 def numWriteVecRf: Int = exuBlockParams.count(_.writeVecRf) 101 102 def numWriteVfRf: Int = exuBlockParams.count(_.writeVfRf) 103 104 def numNoDataWB: Int = exuBlockParams.count(_.hasNoDataWB) 105 106 def dataBitsMax: Int = if (numVecSrc > 0) VLEN else XLEN 107 108 def numDeq: Int = numDeqOutside + exuBlockParams.length 109 110 def JmpCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.jmp)).sum 111 112 def BrhCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.brh)).sum 113 114 def I2fCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.i2f)).sum 115 116 def CsrCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.csr)).sum 117 118 def AluCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.alu)).sum 119 120 def MulCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.mul)).sum 121 122 def DivCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.div)).sum 123 124 def FenceCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fence)).sum 125 126 def BkuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.bku)).sum 127 128 def VsetCnt: Int = exuBlockParams.map(_.fuConfigs.count(x => x.fuType == FuType.vsetiwi || x.fuType == FuType.vsetiwf || x.fuType == FuType.vsetfwf)).sum 129 130 def FmacCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fmac)).sum 131 132 def FmiscCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fmisc)).sum 133 134 def fDivSqrtCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.fDivSqrt)).sum 135 136 def LduCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.name == "ldu")).sum 137 138 def StaCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.name == "sta")).sum 139 140 def MouCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.mou)).sum 141 142 def StdCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.name == "std")).sum 143 144 def VipuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vipu)).sum 145 146 def VfpuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vfpu)).sum 147 148 def VlduCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vldu)).sum 149 150 def VstuCnt: Int = exuBlockParams.map(_.fuConfigs.count(_.fuType == FuType.vstu)).sum 151 152 def numRedirect: Int = exuBlockParams.count(_.hasRedirect) 153 154 def iqWakeUpSourcePairs: Seq[WakeUpConfig] = exuBlockParams.flatMap(_.iqWakeUpSourcePairs) 155 156 /** Get exu source wake up 157 * @todo replace with 158 * exuBlockParams 159 * .flatMap(_.iqWakeUpSinkPairs) 160 * .map(_.source) 161 * .distinctBy(_.name) 162 * when xiangshan is updated to 2.13.11 163 */ 164 def wakeUpInExuSources: Seq[WakeUpSource] = { 165 SeqUtils.distinctBy( 166 exuBlockParams 167 .flatMap(_.iqWakeUpSinkPairs) 168 .map(_.source) 169 )(_.name) 170 } 171 172 def wakeUpOutExuSources: Seq[WakeUpSource] = { 173 SeqUtils.distinctBy( 174 exuBlockParams 175 .flatMap(_.iqWakeUpSourcePairs) 176 .map(_.source) 177 )(_.name) 178 } 179 180 def wakeUpToExuSinks = exuBlockParams 181 .flatMap(_.iqWakeUpSourcePairs) 182 .map(_.sink).distinct 183 184 def numWakeupFromIQ: Int = wakeUpInExuSources.size 185 186 def numAllWakeUp: Int = numWakeupFromWB + numWakeupFromIQ + numWakeupFromOthers 187 188 def getFuCfgs: Seq[FuConfig] = exuBlockParams.flatMap(_.fuConfigs).distinct 189 190 // cfgs(exuIdx)(set of exu's wb) 191 def getWbCfgs: Seq[Set[WbConfig]] = { 192 exuBlockParams.map(exu => exu.wbPortConfigs.toSet) 193 } 194 195 def canAccept(fuType: UInt): Bool = { 196 Cat(getFuCfgs.map(_.fuType.U === fuType)).orR 197 } 198 199 def bindBackendParam(param: BackendParams): Unit = { 200 backendParam = param 201 } 202 203 def genExuInputDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[ExuInput]] = { 204 MixedVec(this.exuBlockParams.map(x => DecoupledIO(x.genExuInputBundle))) 205 } 206 207 def genExuOutputDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[ExuOutput]] = { 208 MixedVec(this.exuBlockParams.map(x => DecoupledIO(x.genExuOutputBundle))) 209 } 210 211 def genExuOutputValidBundle(implicit p: Parameters): MixedVec[ValidIO[ExuOutput]] = { 212 MixedVec(this.exuBlockParams.map(x => ValidIO(x.genExuOutputBundle))) 213 } 214 215 def genIssueDecoupledBundle(implicit p: Parameters): MixedVec[DecoupledIO[IssueQueueIssueBundle]] = { 216 MixedVec(exuBlockParams.map(x => DecoupledIO(new IssueQueueIssueBundle(this, x, pregBits, vaddrBits)))) 217 } 218 219 def genWakeUpSourceValidBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueWakeUpBundle]] = { 220 MixedVec(exuBlockParams.map(x => ValidIO(new IssueQueueWakeUpBundle(x.name, backendParam)))) 221 } 222 223 def genWakeUpSinkValidBundle(implicit p: Parameters): MixedVec[ValidIO[IssueQueueWakeUpBundle]] = { 224 MixedVec(this.wakeUpInExuSources.map(x => ValidIO(new IssueQueueWakeUpBundle(x.name, backendParam)))) 225 } 226 227 def genOGRespBundle(implicit p: Parameters) = { 228 implicit val issueBlockParams = this 229 MixedVec(exuBlockParams.map(_ => new OGRespBundle)) 230 } 231 232 def genWbFuBusyTableWriteBundle()(implicit p: Parameters) = { 233 implicit val issueBlockParams = this 234 MixedVec(exuBlockParams.map(x => new WbFuBusyTableWriteBundle(x))) 235 } 236 237 def genWbFuBusyTableReadBundle()(implicit p: Parameters) = { 238 implicit val issueBlockParams = this 239 MixedVec(exuBlockParams.map{ x => 240 new WbFuBusyTableReadBundle(x) 241 }) 242 } 243 244 def genWbConflictBundle()(implicit p: Parameters) = { 245 implicit val issueBlockParams = this 246 MixedVec(exuBlockParams.map { x => 247 new WbConflictBundle(x) 248 }) 249 } 250 251 def getIQName = { 252 "IssueQueue" ++ getFuCfgs.map(_.name).distinct.map(_.capitalize).reduce(_ ++ _) 253 } 254} 255