1730cfbc0SXuan Hu/*************************************************************************************** 2730cfbc0SXuan Hu * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3730cfbc0SXuan Hu * Copyright (c) 2020-2021 Peng Cheng Laboratory 4730cfbc0SXuan Hu * 5730cfbc0SXuan Hu * XiangShan is licensed under Mulan PSL v2. 6730cfbc0SXuan Hu * You can use this software according to the terms and conditions of the Mulan PSL v2. 7730cfbc0SXuan Hu * You may obtain a copy of Mulan PSL v2 at: 8730cfbc0SXuan Hu * http://license.coscl.org.cn/MulanPSL2 9730cfbc0SXuan Hu * 10730cfbc0SXuan Hu * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11730cfbc0SXuan Hu * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12730cfbc0SXuan Hu * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13730cfbc0SXuan Hu * 14730cfbc0SXuan Hu * See the Mulan PSL v2 for more details. 15730cfbc0SXuan Hu ***************************************************************************************/ 16730cfbc0SXuan Hu 17730cfbc0SXuan Hupackage xiangshan.backend 18730cfbc0SXuan Hu 19730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters 20730cfbc0SXuan Huimport chisel3._ 21730cfbc0SXuan Huimport chisel3.util._ 22730cfbc0SXuan Huimport xiangshan.backend.Bundles._ 23730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig._ 244e9757ccSfdyimport xiangshan.backend.datapath.RdConfig._ 25c34b4b06SXuan Huimport xiangshan.backend.datapath.WbConfig._ 26c34b4b06SXuan Huimport xiangshan.backend.datapath.{WakeUpConfig, WbArbiterParams} 27730cfbc0SXuan Huimport xiangshan.backend.exu.ExeUnitParams 28730cfbc0SXuan Huimport xiangshan.backend.issue._ 29730cfbc0SXuan Huimport xiangshan.backend.regfile._ 30730cfbc0SXuan Hu 31*39c59369SXuan Huimport scala.reflect.{ClassTag, classTag} 32c34b4b06SXuan Hu 33730cfbc0SXuan Hucase class BackendParams( 34730cfbc0SXuan Hu schdParams : Map[SchedulerType, SchdBlockParams], 35730cfbc0SXuan Hu pregParams : Seq[PregParams], 36bf35baadSXuan Hu iqWakeUpParams : Seq[WakeUpConfig], 37730cfbc0SXuan Hu) { 384e9757ccSfdy 394e9757ccSfdy configChecks 404e9757ccSfdy 41730cfbc0SXuan Hu def intSchdParams = schdParams.get(IntScheduler()) 42730cfbc0SXuan Hu def vfSchdParams = schdParams.get(VfScheduler()) 43730cfbc0SXuan Hu def memSchdParams = schdParams.get(MemScheduler()) 44730cfbc0SXuan Hu def allSchdParams: Seq[SchdBlockParams] = 45730cfbc0SXuan Hu (Seq(intSchdParams) :+ vfSchdParams :+ memSchdParams) 46730cfbc0SXuan Hu .filter(_.nonEmpty) 47730cfbc0SXuan Hu .map(_.get) 48730cfbc0SXuan Hu def allIssueParams: Seq[IssueBlockParams] = 49730cfbc0SXuan Hu allSchdParams.map(_.issueBlockParams).flatten 50730cfbc0SXuan Hu def allExuParams: Seq[ExeUnitParams] = 51730cfbc0SXuan Hu allIssueParams.map(_.exuBlockParams).flatten 52730cfbc0SXuan Hu 53730cfbc0SXuan Hu def intPregParams: IntPregParams = pregParams.collectFirst { case x: IntPregParams => x }.get 54730cfbc0SXuan Hu def vfPregParams: VfPregParams = pregParams.collectFirst { case x: VfPregParams => x }.get 55*39c59369SXuan Hu def getPregParams: Map[DataConfig, PregParams] = { 56*39c59369SXuan Hu pregParams.map(x => (x.dataCfg, x)).toMap 57*39c59369SXuan Hu } 58*39c59369SXuan Hu 59c0be7f33SXuan Hu def pregIdxWidth = pregParams.map(_.addrWidth).max 60730cfbc0SXuan Hu 6198639abbSXuan Hu def numSrc : Int = allSchdParams.map(_.issueBlockParams.map(_.numSrc).max).max 6298639abbSXuan Hu def numRegSrc : Int = allSchdParams.map(_.issueBlockParams.map(_.numRegSrc).max).max 63d6f9198fSXuan Hu def numVecRegSrc: Int = allSchdParams.map(_.issueBlockParams.map(_.numVecSrc).max).max 64d6f9198fSXuan Hu 6598639abbSXuan Hu 66730cfbc0SXuan Hu def AluCnt = allSchdParams.map(_.AluCnt).sum 67730cfbc0SXuan Hu def StaCnt = allSchdParams.map(_.StaCnt).sum 68730cfbc0SXuan Hu def StdCnt = allSchdParams.map(_.StdCnt).sum 69730cfbc0SXuan Hu def LduCnt = allSchdParams.map(_.LduCnt).sum 704ee69032SzhanglyGit def VlduCnt = allSchdParams.map(_.VlduCnt).sum 71730cfbc0SXuan Hu def LsExuCnt = StaCnt + LduCnt 72730cfbc0SXuan Hu def JmpCnt = allSchdParams.map(_.JmpCnt).sum 73730cfbc0SXuan Hu def BrhCnt = allSchdParams.map(_.BrhCnt).sum 74730cfbc0SXuan Hu def IqCnt = allSchdParams.map(_.issueBlockParams.length).sum 75730cfbc0SXuan Hu 76730cfbc0SXuan Hu def numPcReadPort = allSchdParams.map(_.numPcReadPort).sum 77730cfbc0SXuan Hu 78*39c59369SXuan Hu def numPregRd(dataCfg: DataConfig) = this.getRfReadSize(dataCfg) 79*39c59369SXuan Hu def numPregWb(dataCfg: DataConfig) = this.getRfWriteSize(dataCfg) 80*39c59369SXuan Hu 81730cfbc0SXuan Hu def numNoDataWB = allSchdParams.map(_.numNoDataWB).sum 82730cfbc0SXuan Hu def numExu = allSchdParams.map(_.numExu).sum 83e2e5f6b0SXuan Hu def vconfigPort = 0 // Todo: remove it 84730cfbc0SXuan Hu 85730cfbc0SXuan Hu def numException = allExuParams.count(_.exceptionOut.nonEmpty) 86730cfbc0SXuan Hu 87730cfbc0SXuan Hu def numRedirect = allSchdParams.map(_.numRedirect).sum 88730cfbc0SXuan Hu 89730cfbc0SXuan Hu def genIntWriteBackBundle(implicit p: Parameters) = { 90*39c59369SXuan Hu Seq.fill(this.getIntRfWriteSize)(new RfWritePortWithConfig(IntData(), intPregParams.addrWidth)) 91730cfbc0SXuan Hu } 92730cfbc0SXuan Hu 93730cfbc0SXuan Hu def genVfWriteBackBundle(implicit p: Parameters) = { 94*39c59369SXuan Hu Seq.fill(this.getVfRfWriteSize)(new RfWritePortWithConfig(VecData(), vfPregParams.addrWidth)) 95730cfbc0SXuan Hu } 96730cfbc0SXuan Hu 97730cfbc0SXuan Hu def genWriteBackBundles(implicit p: Parameters): Seq[RfWritePortWithConfig] = { 98730cfbc0SXuan Hu genIntWriteBackBundle ++ genVfWriteBackBundle 99730cfbc0SXuan Hu } 100730cfbc0SXuan Hu 101730cfbc0SXuan Hu def genWrite2CtrlBundles(implicit p: Parameters): MixedVec[ValidIO[ExuOutput]] = { 102730cfbc0SXuan Hu MixedVec(allSchdParams.map(_.genExuOutputValidBundle.flatten).reduce(_ ++ _)) 103730cfbc0SXuan Hu } 104730cfbc0SXuan Hu 105730cfbc0SXuan Hu def getIntWbArbiterParams: WbArbiterParams = { 106*39c59369SXuan Hu val intWbCfgs: Seq[IntWB] = allSchdParams.flatMap(_.getWbCfgs.flatten.flatten.filter(_.writeInt)).map(_.asInstanceOf[IntWB]) 107*39c59369SXuan Hu datapath.WbArbiterParams(intWbCfgs, intPregParams, this) 108730cfbc0SXuan Hu } 109730cfbc0SXuan Hu 110730cfbc0SXuan Hu def getVfWbArbiterParams: WbArbiterParams = { 111*39c59369SXuan Hu val vfWbCfgs: Seq[VfWB] = allSchdParams.flatMap(_.getWbCfgs.flatten.flatten.filter(x => x.writeVec || x.writeFp)).map(_.asInstanceOf[VfWB]) 112*39c59369SXuan Hu datapath.WbArbiterParams(vfWbCfgs, vfPregParams, this) 113730cfbc0SXuan Hu } 1148d29ec32Sczw 115c34b4b06SXuan Hu /** 116c34b4b06SXuan Hu * Get regfile read port params 117*39c59369SXuan Hu * 118*39c59369SXuan Hu * @param dataCfg [[IntData]] or [[VecData]] 119c34b4b06SXuan Hu * @return Seq[port->Seq[(exuIdx, priority)] 120c34b4b06SXuan Hu */ 121*39c59369SXuan Hu def getRdPortParams(dataCfg: DataConfig) = { 122c34b4b06SXuan Hu // port -> Seq[exuIdx, priority] 123c34b4b06SXuan Hu val cfgs: Seq[(Int, Seq[(Int, Int)])] = allExuParams 124c34b4b06SXuan Hu .flatMap(x => x.rfrPortConfigs.flatten.map(xx => (xx, x.exuIdx))) 125*39c59369SXuan Hu .filter { x => x._1.getDataConfig == dataCfg } 126c34b4b06SXuan Hu .map(x => (x._1.port, (x._2, x._1.priority))) 127c34b4b06SXuan Hu .groupBy(_._1) 128c34b4b06SXuan Hu .map(x => (x._1, x._2.map(_._2).sortBy({ case (priority, _) => priority }))) 129c34b4b06SXuan Hu .toSeq 130c34b4b06SXuan Hu .sortBy(_._1) 131c34b4b06SXuan Hu cfgs 132c34b4b06SXuan Hu } 133c34b4b06SXuan Hu 134c34b4b06SXuan Hu /** 135c34b4b06SXuan Hu * Get regfile write back port params 136c34b4b06SXuan Hu * 137*39c59369SXuan Hu * @param dataCfg [[IntData]] or [[VecData]] 138c34b4b06SXuan Hu * @return Seq[port->Seq[(exuIdx, priority)] 139c34b4b06SXuan Hu */ 140*39c59369SXuan Hu def getWbPortParams(dataCfg: DataConfig) = { 141c34b4b06SXuan Hu val cfgs: Seq[(Int, Seq[(Int, Int)])] = allExuParams 142*39c59369SXuan Hu .flatMap(x => x.wbPortConfigs.map(xx => (xx, x.exuIdx))) 143*39c59369SXuan Hu .filter { x => x._1.dataCfg == dataCfg } 144c34b4b06SXuan Hu .map(x => (x._1.port, (x._2, x._1.priority))) 145c34b4b06SXuan Hu .groupBy(_._1) 146c34b4b06SXuan Hu .map(x => (x._1, x._2.map(_._2))) 147c34b4b06SXuan Hu .toSeq 148c34b4b06SXuan Hu .sortBy(_._1) 149c34b4b06SXuan Hu cfgs 150c34b4b06SXuan Hu } 151c34b4b06SXuan Hu 152*39c59369SXuan Hu def getRdPortIndices(dataCfg: DataConfig) = { 153*39c59369SXuan Hu this.getRdPortParams(dataCfg).map(_._1) 154*39c59369SXuan Hu } 155*39c59369SXuan Hu 156*39c59369SXuan Hu def getWbPortIndices(dataCfg: DataConfig) = { 157*39c59369SXuan Hu this.getWbPortParams(dataCfg).map(_._1) 158*39c59369SXuan Hu } 159*39c59369SXuan Hu 160*39c59369SXuan Hu def getRdCfgs[T <: RdConfig](implicit tag: ClassTag[T]): Seq[Seq[Seq[RdConfig]]] = { 161*39c59369SXuan Hu val rdCfgs: Seq[Seq[Seq[RdConfig]]] = allIssueParams.map( 162*39c59369SXuan Hu _.exuBlockParams.map( 163*39c59369SXuan Hu _.rfrPortConfigs.map( 164*39c59369SXuan Hu _.collectFirst{ case x: T => x } 165*39c59369SXuan Hu .getOrElse(NoRD()) 166*39c59369SXuan Hu ) 167*39c59369SXuan Hu ) 168*39c59369SXuan Hu ) 169*39c59369SXuan Hu rdCfgs 170*39c59369SXuan Hu } 171*39c59369SXuan Hu 172*39c59369SXuan Hu def getAllWbCfgs: Seq[Seq[Set[PregWB]]] = { 173*39c59369SXuan Hu allIssueParams.map(_.exuBlockParams.map(_.wbPortConfigs.toSet)) 174*39c59369SXuan Hu } 175*39c59369SXuan Hu 176*39c59369SXuan Hu def getWbCfgs[T <: PregWB](implicit tag: ClassTag[T]): Seq[Seq[PregWB]] = { 177*39c59369SXuan Hu val wbCfgs: Seq[Seq[PregWB]] = allIssueParams.map(_.exuBlockParams.map(_.wbPortConfigs.collectFirst{ case x: T => x }.getOrElse(NoWB()))) 178*39c59369SXuan Hu wbCfgs 179*39c59369SXuan Hu } 180*39c59369SXuan Hu 181*39c59369SXuan Hu /** 182*39c59369SXuan Hu * Get size of read ports of int regfile 183*39c59369SXuan Hu * 184*39c59369SXuan Hu * @return if [[IntPregParams.numRead]] is [[None]], get size of ports in [[IntRD]] 185*39c59369SXuan Hu */ 186*39c59369SXuan Hu def getIntRfReadSize = { 187*39c59369SXuan Hu this.intPregParams.numRead.getOrElse(this.getRdPortIndices(IntData()).size) 188*39c59369SXuan Hu } 189*39c59369SXuan Hu 190*39c59369SXuan Hu /** 191*39c59369SXuan Hu * Get size of write ports of vf regfile 192*39c59369SXuan Hu * 193*39c59369SXuan Hu * @return if [[IntPregParams.numWrite]] is [[None]], get size of ports in [[IntWB]] 194*39c59369SXuan Hu */ 195*39c59369SXuan Hu def getIntRfWriteSize = { 196*39c59369SXuan Hu this.intPregParams.numWrite.getOrElse(this.getWbPortIndices(IntData()).size) 197*39c59369SXuan Hu } 198*39c59369SXuan Hu 199*39c59369SXuan Hu /** 200*39c59369SXuan Hu * Get size of read ports of int regfile 201*39c59369SXuan Hu * 202*39c59369SXuan Hu * @return if [[VfPregParams.numRead]] is [[None]], get size of ports in [[VfRD]] 203*39c59369SXuan Hu */ 204*39c59369SXuan Hu def getVfRfReadSize = { 205*39c59369SXuan Hu this.vfPregParams.numRead.getOrElse(this.getRdPortIndices(VecData()).size) 206*39c59369SXuan Hu } 207*39c59369SXuan Hu 208*39c59369SXuan Hu /** 209*39c59369SXuan Hu * Get size of write ports of vf regfile 210*39c59369SXuan Hu * 211*39c59369SXuan Hu * @return if [[VfPregParams.numWrite]] is [[None]], get size of ports in [[VfWB]] 212*39c59369SXuan Hu */ 213*39c59369SXuan Hu def getVfRfWriteSize = { 214*39c59369SXuan Hu this.vfPregParams.numWrite.getOrElse(this.getWbPortIndices(VecData()).size) 215*39c59369SXuan Hu } 216*39c59369SXuan Hu 217*39c59369SXuan Hu def getRfReadSize(dataCfg: DataConfig) = { 218*39c59369SXuan Hu this.getPregParams(dataCfg).numRead.getOrElse(this.getRdPortIndices(dataCfg).size) 219*39c59369SXuan Hu } 220*39c59369SXuan Hu 221*39c59369SXuan Hu def getRfWriteSize(dataCfg: DataConfig) = { 222*39c59369SXuan Hu this.getPregParams(dataCfg).numWrite.getOrElse(this.getWbPortIndices(dataCfg).size) 223*39c59369SXuan Hu } 224*39c59369SXuan Hu 225cdac04a3SXuan Hu def getExuIdx(name: String): Int = { 226cdac04a3SXuan Hu val exuParams = allExuParams 227acb0b98eSXuan Hu if (name != "WB") { 228acb0b98eSXuan Hu val foundExu = exuParams.find(_.name == name) 229acb0b98eSXuan Hu require(foundExu.nonEmpty, s"exu $name not find") 230acb0b98eSXuan Hu foundExu.get.exuIdx 231acb0b98eSXuan Hu } else 232cdac04a3SXuan Hu -1 233cdac04a3SXuan Hu } 234cdac04a3SXuan Hu 235c0be7f33SXuan Hu def getExuName(idx: Int): String = { 236c0be7f33SXuan Hu val exuParams = allExuParams 237c0be7f33SXuan Hu exuParams(idx).name 238c0be7f33SXuan Hu } 239c0be7f33SXuan Hu 2408d29ec32Sczw def getIntWBExeGroup: Map[Int, Seq[ExeUnitParams]] = allExuParams.groupBy(x => x.getIntWBPort.getOrElse(IntWB(port = -1)).port).filter(_._1 != -1) 2418d29ec32Sczw def getVfWBExeGroup: Map[Int, Seq[ExeUnitParams]] = allExuParams.groupBy(x => x.getVfWBPort.getOrElse(VfWB(port = -1)).port).filter(_._1 != -1) 2424e9757ccSfdy 243*39c59369SXuan Hu private def isContinuous(portIndices: Seq[Int]): Boolean = { 244*39c59369SXuan Hu val portIndicesSet = portIndices.toSet 245*39c59369SXuan Hu portIndicesSet.min == 0 && portIndicesSet.max == portIndicesSet.size - 1 246*39c59369SXuan Hu } 247*39c59369SXuan Hu 2484e9757ccSfdy def configChecks = { 249*39c59369SXuan Hu checkReadPortContinuous 250*39c59369SXuan Hu checkWritePortContinuous 251*39c59369SXuan Hu configCheck 252*39c59369SXuan Hu } 253*39c59369SXuan Hu 254*39c59369SXuan Hu def checkReadPortContinuous = { 255*39c59369SXuan Hu pregParams.foreach { x => 256*39c59369SXuan Hu if (x.numRead.isEmpty) { 257*39c59369SXuan Hu val portIndices: Seq[Int] = getRdPortIndices(x.dataCfg) 258*39c59369SXuan Hu require(isContinuous(portIndices), 259*39c59369SXuan Hu s"The read ports of ${x.getClass.getSimpleName} should be continuous, " + 260*39c59369SXuan Hu s"when numRead of ${x.getClass.getSimpleName} is None. The read port indices are $portIndices") 261*39c59369SXuan Hu } 262*39c59369SXuan Hu } 263*39c59369SXuan Hu } 264*39c59369SXuan Hu 265*39c59369SXuan Hu def checkWritePortContinuous = { 266*39c59369SXuan Hu pregParams.foreach { x => 267*39c59369SXuan Hu if (x.numWrite.isEmpty) { 268*39c59369SXuan Hu val portIndices: Seq[Int] = getWbPortIndices(x.dataCfg) 269*39c59369SXuan Hu require( 270*39c59369SXuan Hu isContinuous(portIndices), 271*39c59369SXuan Hu s"The write ports of ${x.getClass.getSimpleName} should be continuous, " + 272*39c59369SXuan Hu s"when numWrite of ${x.getClass.getSimpleName} is None. The write port indices are $portIndices" 273*39c59369SXuan Hu ) 274*39c59369SXuan Hu } 275*39c59369SXuan Hu } 276*39c59369SXuan Hu } 277*39c59369SXuan Hu 278*39c59369SXuan Hu def configCheck = { 2794e9757ccSfdy // check 0 2804e9757ccSfdy val maxPortSource = 2 2814e9757ccSfdy 2824e9757ccSfdy allExuParams.map { 2834e9757ccSfdy case exuParam => exuParam.wbPortConfigs.collectFirst { case x: IntWB => x } 2844e9757ccSfdy }.filter(_.isDefined).groupBy(_.get.port).foreach { 2854e9757ccSfdy case (wbPort, priorities) => assert(priorities.size <= maxPortSource, "There has " + priorities.size + " exu's " + "Int WBport is " + wbPort + ", but the maximum is " + maxPortSource + ".") 2864e9757ccSfdy } 2874e9757ccSfdy allExuParams.map { 2884e9757ccSfdy case exuParam => exuParam.wbPortConfigs.collectFirst { case x: VfWB => x } 2894e9757ccSfdy }.filter(_.isDefined).groupBy(_.get.port).foreach { 2904e9757ccSfdy case (wbPort, priorities) => assert(priorities.size <= maxPortSource, "There has " + priorities.size + " exu's " + "Vf WBport is " + wbPort + ", but the maximum is " + maxPortSource + ".") 2914e9757ccSfdy } 2924e9757ccSfdy 2934e9757ccSfdy // check 1 2944e9757ccSfdy val wbTypes = Seq(IntWB(), VfWB()) 2954e9757ccSfdy val rdTypes = Seq(IntRD(), VfRD()) 2964e9757ccSfdy for(wbType <- wbTypes){ 2974e9757ccSfdy for(rdType <- rdTypes){ 2984e9757ccSfdy allExuParams.map { 2994e9757ccSfdy case exuParam => 3004e9757ccSfdy val wbPortConfigs = exuParam.wbPortConfigs 3014e9757ccSfdy val wbConfigs = wbType match{ 3024e9757ccSfdy case _: IntWB => wbPortConfigs.collectFirst { case x: IntWB => x } 3034e9757ccSfdy case _: VfWB => wbPortConfigs.collectFirst { case x: VfWB => x } 3044e9757ccSfdy case _ => None 3054e9757ccSfdy } 3064e9757ccSfdy val rfReadPortConfigs = exuParam.rfrPortConfigs 3074e9757ccSfdy val rdConfigs = rdType match{ 3084e9757ccSfdy case _: IntRD => rfReadPortConfigs.flatten.filter(_.isInstanceOf[IntRD]) 3094e9757ccSfdy case _: VfRD => rfReadPortConfigs.flatten.filter(_.isInstanceOf[VfRD]) 3104e9757ccSfdy case _ => Seq() 3114e9757ccSfdy } 3124e9757ccSfdy (wbConfigs, rdConfigs) 3134e9757ccSfdy }.filter(_._1.isDefined) 3144e9757ccSfdy .sortBy(_._1.get.priority) 3154e9757ccSfdy .groupBy(_._1.get.port).map { 3164e9757ccSfdy case (_, intWbRdPairs) => 3174e9757ccSfdy intWbRdPairs.map(_._2).flatten 3184e9757ccSfdy }.map(rdCfgs => rdCfgs.groupBy(_.port).foreach { 3194e9757ccSfdy case (_, rdCfgs) => 3204e9757ccSfdy rdCfgs.zip(rdCfgs.drop(1)).foreach { case (cfg0, cfg1) => assert(cfg0.priority <= cfg1.priority) } 3214e9757ccSfdy }) 3224e9757ccSfdy } 3234e9757ccSfdy } 3244e9757ccSfdy } 325730cfbc0SXuan Hu} 326730cfbc0SXuan Hu 327730cfbc0SXuan Hu 328730cfbc0SXuan Hu 329730cfbc0SXuan Hu 330