xref: /XiangShan/src/main/scala/xiangshan/backend/exu/ExeUnitParams.scala (revision dd473fffdbc9bcdbae062bfc5210e67b6e848a47)
1730cfbc0SXuan Hupackage xiangshan.backend.exu
2730cfbc0SXuan Hu
3730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
62e0a7dc5Sfdyimport xiangshan.HasXSParameter
7*dd473fffSXuan Huimport xiangshan.backend.BackendParams
8730cfbc0SXuan Huimport xiangshan.backend.Bundles.{ExuInput, ExuOutput}
9730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig.DataConfig
10730cfbc0SXuan Huimport xiangshan.backend.datapath.RdConfig._
11d387a573SXuan Huimport xiangshan.backend.datapath.WakeUpConfig
122e0a7dc5Sfdyimport xiangshan.backend.datapath.WbConfig.{IntWB, VfWB, WbConfig}
13730cfbc0SXuan Huimport xiangshan.backend.fu.{FuConfig, FuType}
14730cfbc0SXuan Huimport xiangshan.backend.issue.{IntScheduler, SchedulerType, VfScheduler}
15730cfbc0SXuan Hu
16730cfbc0SXuan Hucase class ExeUnitParams(
1708017d75SXuan Hu  name          : String,
18730cfbc0SXuan Hu  fuConfigs     : Seq[FuConfig],
19730cfbc0SXuan Hu  wbPortConfigs : Seq[WbConfig],
20730cfbc0SXuan Hu  rfrPortConfigs: Seq[Seq[RdConfig]],
21730cfbc0SXuan Hu)(
22730cfbc0SXuan Hu  implicit
23730cfbc0SXuan Hu  val schdType: SchedulerType,
24730cfbc0SXuan Hu) {
25d387a573SXuan Hu  // calculated configs
26d387a573SXuan Hu  var iqWakeUpSourcePairs: Seq[WakeUpConfig] = Seq()
27d387a573SXuan Hu  var iqWakeUpSinkPairs: Seq[WakeUpConfig] = Seq()
28bf35baadSXuan Hu  // used in bypass to select data of exu output
29bf35baadSXuan Hu  var exuIdx: Int = -1
30*dd473fffSXuan Hu  var backendParam: BackendParams = null
31d387a573SXuan Hu
32730cfbc0SXuan Hu  val numIntSrc: Int = fuConfigs.map(_.numIntSrc).max
33730cfbc0SXuan Hu  val numFpSrc: Int = fuConfigs.map(_.numFpSrc).max
34730cfbc0SXuan Hu  val numVecSrc: Int = fuConfigs.map(_.numVecSrc).max
35730cfbc0SXuan Hu  val numVfSrc: Int = fuConfigs.map(_.numVfSrc).max
36730cfbc0SXuan Hu  val numRegSrc: Int = fuConfigs.map(_.numRegSrc).max
37730cfbc0SXuan Hu  val numSrc: Int = fuConfigs.map(_.numSrc).max
38730cfbc0SXuan Hu  val dataBitsMax: Int = fuConfigs.map(_.dataBits).max
39730cfbc0SXuan Hu  val readIntRf: Boolean = numIntSrc > 0
40730cfbc0SXuan Hu  val readFpRf: Boolean = numFpSrc > 0
41730cfbc0SXuan Hu  val readVecRf: Boolean = numVecSrc > 0
42730cfbc0SXuan Hu  val writeIntRf: Boolean = fuConfigs.map(_.writeIntRf).reduce(_ || _)
43730cfbc0SXuan Hu  val writeFpRf: Boolean = fuConfigs.map(_.writeFpRf).reduce(_ || _)
44730cfbc0SXuan Hu  val writeVecRf: Boolean = fuConfigs.map(_.writeVecRf).reduce(_ || _)
45730cfbc0SXuan Hu  val writeVfRf: Boolean = writeFpRf || writeVecRf
46730cfbc0SXuan Hu  val writeFflags: Boolean = fuConfigs.map(_.writeFflags).reduce(_ || _)
47a8db15d8Sfdy  val writeVxsat: Boolean = fuConfigs.map(_.writeVxsat).reduce(_ || _)
48730cfbc0SXuan Hu  val hasNoDataWB: Boolean = fuConfigs.map(_.hasNoDataWB).reduce(_ || _)
49730cfbc0SXuan Hu  val hasRedirect: Boolean = fuConfigs.map(_.hasRedirect).reduce(_ || _)
50730cfbc0SXuan Hu  val hasPredecode: Boolean = fuConfigs.map(_.hasPredecode).reduce(_ || _)
51730cfbc0SXuan Hu  val exceptionOut: Seq[Int] = fuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted
52730cfbc0SXuan Hu  val hasLoadError: Boolean = fuConfigs.map(_.hasLoadError).reduce(_ || _)
53730cfbc0SXuan Hu  val flushPipe: Boolean = fuConfigs.map(_.flushPipe).reduce(_ || _)
54730cfbc0SXuan Hu  val replayInst: Boolean = fuConfigs.map(_.replayInst).reduce(_ || _)
55730cfbc0SXuan Hu  val trigger: Boolean = fuConfigs.map(_.trigger).reduce(_ || _)
56730cfbc0SXuan Hu  val needExceptionGen: Boolean = exceptionOut.nonEmpty || flushPipe || replayInst || trigger
57730cfbc0SXuan Hu  val needPc: Boolean = fuConfigs.map(_.needPc).reduce(_ || _)
58730cfbc0SXuan Hu  val needSrcFrm: Boolean = fuConfigs.map(_.needSrcFrm).reduce(_ || _)
59730cfbc0SXuan Hu  val needFPUCtrl: Boolean = fuConfigs.map(_.needFPUCtrl).reduce(_ || _)
60b6b11f60SXuan Hu  val needVPUCtrl: Boolean = fuConfigs.map(_.needVecCtrl).reduce(_ || _)
61730cfbc0SXuan Hu  val wbPregIdxWidth = if (wbPortConfigs.nonEmpty) wbPortConfigs.map(_.pregIdxWidth).max else 0
62730cfbc0SXuan Hu
632e0a7dc5Sfdy  val writeIntFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeIntRf)
642e0a7dc5Sfdy  val writeVfFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeFpRf || x.writeVecRf)
652e0a7dc5Sfdy
66bf44d649SXuan Hu  /**
67bf44d649SXuan Hu    * Check if this exu has certain latency
68bf44d649SXuan Hu    */
69bf44d649SXuan Hu  def latencyCertain: Boolean = fuConfigs.map(x => x.latency.latencyVal.nonEmpty).reduce(_ && _)
70bf44d649SXuan Hu  def intLatencyCertain: Boolean = writeIntFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
71bf44d649SXuan Hu  def vfLatencyCertain: Boolean = writeVfFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
722e0a7dc5Sfdy
73bf44d649SXuan Hu  /**
74bf44d649SXuan Hu    * Get mapping from FuType to Latency value.
75bf44d649SXuan Hu    * If [[latencyCertain]] is false, get empty [[Map]]
76bf44d649SXuan Hu    *
77bf44d649SXuan Hu    * @return Map[FuType, Latency]
78bf44d649SXuan Hu    */
79bf44d649SXuan Hu  def fuLatencyMap: Map[Int, Int] = {
80bf44d649SXuan Hu    if (latencyCertain)
81bf44d649SXuan Hu      fuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
82bf44d649SXuan Hu    else
83bf44d649SXuan Hu      Map()
84bf44d649SXuan Hu  }
852e0a7dc5Sfdy
86bf44d649SXuan Hu  /**
87bf44d649SXuan Hu    * Get set of latency of function units.
88bf44d649SXuan Hu    * If [[latencyCertain]] is false, get empty [[Set]]
89bf44d649SXuan Hu    *
90bf44d649SXuan Hu    * @return Set[Latency]
91bf44d649SXuan Hu    */
92bf44d649SXuan Hu  def fuLatancySet: Set[Int] = fuLatencyMap.values.toSet
932e0a7dc5Sfdy
94bf44d649SXuan Hu  def latencyValMax: Int = fuLatancySet.fold(0)(_ max _)
95bf44d649SXuan Hu
96bf44d649SXuan Hu  def intFuLatencyMap: Map[Int, Int] = {
97bf44d649SXuan Hu    if (intLatencyCertain)
98bf44d649SXuan Hu      writeIntFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
99bf44d649SXuan Hu    else
100bf44d649SXuan Hu      Map()
101bf44d649SXuan Hu  }
102bf44d649SXuan Hu
103bf44d649SXuan Hu  def intLatencyValMax: Int = intFuLatencyMap.values.fold(0)(_ max _)
104bf44d649SXuan Hu
105bf44d649SXuan Hu  def vfFuLatencyMap: Map[Int, Int] = {
106bf44d649SXuan Hu    if (vfLatencyCertain)
107bf44d649SXuan Hu      writeVfFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
108bf44d649SXuan Hu    else
109bf44d649SXuan Hu      Map()
110bf44d649SXuan Hu  }
111bf44d649SXuan Hu
112bf44d649SXuan Hu  def vfLatencyValMax: Int = vfFuLatencyMap.values.fold(0)(_ max _)
113bf44d649SXuan Hu
114bf44d649SXuan Hu  /**
115bf44d649SXuan Hu    * Check if this exu has fixed latency
116bf44d649SXuan Hu    */
117bf44d649SXuan Hu  def isFixedLatency: Boolean = {
118bf44d649SXuan Hu    if (latencyCertain)
119bf44d649SXuan Hu      return fuConfigs.map(x => x.latency.latencyVal.get == fuConfigs.head.latency.latencyVal.get).reduce(_ && _)
120bf44d649SXuan Hu    false
121bf44d649SXuan Hu  }
122ea0f92d8Sczw
123730cfbc0SXuan Hu  def hasCSR: Boolean = fuConfigs.map(_.isCsr).reduce(_ || _)
124730cfbc0SXuan Hu
125730cfbc0SXuan Hu  def hasFence: Boolean = fuConfigs.map(_.isFence).reduce(_ || _)
126730cfbc0SXuan Hu
127730cfbc0SXuan Hu  def hasBrhFu = fuConfigs.map(_.fuType == FuType.brh).reduce(_ || _)
128730cfbc0SXuan Hu
129730cfbc0SXuan Hu  def hasJmpFu = fuConfigs.map(_.fuType == FuType.jmp).reduce(_ || _)
130730cfbc0SXuan Hu
131730cfbc0SXuan Hu  def hasLoadFu = fuConfigs.map(_.fuType == FuType.ldu).reduce(_ || _)
132730cfbc0SXuan Hu
1334ee69032SzhanglyGit  def hasVLoadFu = fuConfigs.map(_.fuType == FuType.vldu).reduce(_ || _)
1344ee69032SzhanglyGit
135730cfbc0SXuan Hu  def hasStoreAddrFu = fuConfigs.map(_.name == "sta").reduce(_ || _)
136730cfbc0SXuan Hu
137730cfbc0SXuan Hu  def hasStdFu = fuConfigs.map(_.name == "std").reduce(_ || _)
138730cfbc0SXuan Hu
1394ee69032SzhanglyGit  def hasMemAddrFu = hasLoadFu || hasStoreAddrFu || hasVLoadFu
140730cfbc0SXuan Hu
141da778e6fSXuan Hu  def hasVecFu = fuConfigs.map(x => FuConfig.VecArithFuConfigs.contains(x)).reduce(_ || _)
142da778e6fSXuan Hu
143730cfbc0SXuan Hu  def getSrcDataType(srcIdx: Int): Set[DataConfig] = {
144730cfbc0SXuan Hu    fuConfigs.map(_.getSrcDataType(srcIdx)).reduce(_ ++ _)
145730cfbc0SXuan Hu  }
146730cfbc0SXuan Hu
147730cfbc0SXuan Hu  def immType: Set[UInt] = fuConfigs.map(x => x.immType).reduce(_ ++ _)
148730cfbc0SXuan Hu
149730cfbc0SXuan Hu  def getWBSource: SchedulerType = {
150730cfbc0SXuan Hu    schdType
151730cfbc0SXuan Hu  }
152730cfbc0SXuan Hu
153730cfbc0SXuan Hu  def hasCrossWb: Boolean = {
154730cfbc0SXuan Hu    schdType match {
155730cfbc0SXuan Hu      case IntScheduler() => writeFpRf || writeVecRf
156730cfbc0SXuan Hu      case VfScheduler() => writeIntRf
157730cfbc0SXuan Hu      case _ => false
158730cfbc0SXuan Hu    }
159730cfbc0SXuan Hu  }
160730cfbc0SXuan Hu
161730cfbc0SXuan Hu  def canAccept(fuType: UInt): Bool = {
162730cfbc0SXuan Hu    Cat(fuConfigs.map(_.fuType.U === fuType)).orR
163730cfbc0SXuan Hu  }
164730cfbc0SXuan Hu
165730cfbc0SXuan Hu  def hasUncertainLatency: Boolean = fuConfigs.map(_.latency.latencyVal.isEmpty).reduce(_ || _)
166730cfbc0SXuan Hu
167*dd473fffSXuan Hu  def bindBackendParam(param: BackendParams): Unit = {
168*dd473fffSXuan Hu    backendParam = param
169*dd473fffSXuan Hu  }
170*dd473fffSXuan Hu
171d387a573SXuan Hu  def updateIQWakeUpConfigs(cfgs: Seq[WakeUpConfig]) = {
172bf35baadSXuan Hu    this.iqWakeUpSourcePairs = cfgs.filter(_.source.name == this.name)
173bf35baadSXuan Hu    this.iqWakeUpSinkPairs = cfgs.filter(_.sink.name == this.name)
174bf35baadSXuan Hu    if (this.isIQWakeUpSource)
175bf35baadSXuan Hu      require(!this.hasUncertainLatency, s"${this.name} is IQ wake up source, but has UncertainLatency")
176bf35baadSXuan Hu  }
177bf35baadSXuan Hu
178bf35baadSXuan Hu  def updateExuIdx(idx: Int): Unit = {
179bf35baadSXuan Hu    this.exuIdx = idx
180d387a573SXuan Hu  }
181d387a573SXuan Hu
182d387a573SXuan Hu  def isIQWakeUpSource = this.iqWakeUpSourcePairs.nonEmpty
183d387a573SXuan Hu
184d387a573SXuan Hu  def isIQWakeUpSink = this.iqWakeUpSinkPairs.nonEmpty
185d387a573SXuan Hu
186730cfbc0SXuan Hu  def getIntWBPort = {
187730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
188730cfbc0SXuan Hu      case x: IntWB => x
189730cfbc0SXuan Hu    }
190730cfbc0SXuan Hu  }
191730cfbc0SXuan Hu
1920162f462Sczw  def getVfWBPort = {
193730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
1940162f462Sczw      case x: VfWB => x
195730cfbc0SXuan Hu    }
196730cfbc0SXuan Hu  }
197730cfbc0SXuan Hu
198730cfbc0SXuan Hu  def getRfReadDataCfgSet: Seq[Set[DataConfig]] = {
199730cfbc0SXuan Hu    val fuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuConfigs.map(_.getRfReadDataCfgSet)
200730cfbc0SXuan Hu    val alignedFuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuSrcsCfgSet.map(x => x ++ Seq.fill(numRegSrc - x.length)(Set[DataConfig]()))
201730cfbc0SXuan Hu
202730cfbc0SXuan Hu    val exuSrcsCfgSet = alignedFuSrcsCfgSet.reduce((x, y) => (x zip y).map { case (cfg1, cfg2) => cfg1 union cfg2 })
203730cfbc0SXuan Hu
204730cfbc0SXuan Hu    exuSrcsCfgSet
205730cfbc0SXuan Hu  }
206730cfbc0SXuan Hu
207730cfbc0SXuan Hu  def genExuModule(implicit p: Parameters): ExeUnit = {
208730cfbc0SXuan Hu    new ExeUnit(this)
209730cfbc0SXuan Hu  }
210730cfbc0SXuan Hu
211730cfbc0SXuan Hu  def genExuInputBundle(implicit p: Parameters): ExuInput = {
212730cfbc0SXuan Hu    new ExuInput(this)
213730cfbc0SXuan Hu  }
214730cfbc0SXuan Hu
215730cfbc0SXuan Hu  def genExuOutputBundle(implicit p: Parameters): ExuOutput = {
216730cfbc0SXuan Hu    new ExuOutput(this)
217730cfbc0SXuan Hu  }
218730cfbc0SXuan Hu}
219