xref: /XiangShan/src/main/scala/xiangshan/backend/exu/ExeUnitParams.scala (revision 39c59369af6e7d78fa72e13aae3735f1a6e98f5c)
1730cfbc0SXuan Hupackage xiangshan.backend.exu
2730cfbc0SXuan Hu
3730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
6dd473fffSXuan Huimport xiangshan.backend.BackendParams
7*39c59369SXuan Huimport xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOutput}
8730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig.DataConfig
9730cfbc0SXuan Huimport xiangshan.backend.datapath.RdConfig._
10*39c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.{IntWB, PregWB, VfWB}
11*39c59369SXuan Huimport xiangshan.backend.datapath.{DataConfig, WakeUpConfig}
12730cfbc0SXuan Huimport xiangshan.backend.fu.{FuConfig, FuType}
13730cfbc0SXuan Huimport xiangshan.backend.issue.{IntScheduler, SchedulerType, VfScheduler}
14730cfbc0SXuan Hu
15730cfbc0SXuan Hucase class ExeUnitParams(
1608017d75SXuan Hu  name          : String,
17730cfbc0SXuan Hu  fuConfigs     : Seq[FuConfig],
18*39c59369SXuan Hu  wbPortConfigs : Seq[PregWB],
19730cfbc0SXuan Hu  rfrPortConfigs: Seq[Seq[RdConfig]],
20730cfbc0SXuan Hu)(
21730cfbc0SXuan Hu  implicit
22730cfbc0SXuan Hu  val schdType: SchedulerType,
23730cfbc0SXuan Hu) {
24d387a573SXuan Hu  // calculated configs
25d387a573SXuan Hu  var iqWakeUpSourcePairs: Seq[WakeUpConfig] = Seq()
26d387a573SXuan Hu  var iqWakeUpSinkPairs: Seq[WakeUpConfig] = Seq()
27bf35baadSXuan Hu  // used in bypass to select data of exu output
28bf35baadSXuan Hu  var exuIdx: Int = -1
29dd473fffSXuan Hu  var backendParam: BackendParams = null
30d387a573SXuan Hu
31730cfbc0SXuan Hu  val numIntSrc: Int = fuConfigs.map(_.numIntSrc).max
32730cfbc0SXuan Hu  val numFpSrc: Int = fuConfigs.map(_.numFpSrc).max
33730cfbc0SXuan Hu  val numVecSrc: Int = fuConfigs.map(_.numVecSrc).max
34730cfbc0SXuan Hu  val numVfSrc: Int = fuConfigs.map(_.numVfSrc).max
35730cfbc0SXuan Hu  val numRegSrc: Int = fuConfigs.map(_.numRegSrc).max
36730cfbc0SXuan Hu  val numSrc: Int = fuConfigs.map(_.numSrc).max
37730cfbc0SXuan Hu  val dataBitsMax: Int = fuConfigs.map(_.dataBits).max
38730cfbc0SXuan Hu  val readIntRf: Boolean = numIntSrc > 0
39730cfbc0SXuan Hu  val readFpRf: Boolean = numFpSrc > 0
40730cfbc0SXuan Hu  val readVecRf: Boolean = numVecSrc > 0
41730cfbc0SXuan Hu  val writeIntRf: Boolean = fuConfigs.map(_.writeIntRf).reduce(_ || _)
42730cfbc0SXuan Hu  val writeFpRf: Boolean = fuConfigs.map(_.writeFpRf).reduce(_ || _)
43730cfbc0SXuan Hu  val writeVecRf: Boolean = fuConfigs.map(_.writeVecRf).reduce(_ || _)
44730cfbc0SXuan Hu  val writeVfRf: Boolean = writeFpRf || writeVecRf
45730cfbc0SXuan Hu  val writeFflags: Boolean = fuConfigs.map(_.writeFflags).reduce(_ || _)
46a8db15d8Sfdy  val writeVxsat: Boolean = fuConfigs.map(_.writeVxsat).reduce(_ || _)
47730cfbc0SXuan Hu  val hasNoDataWB: Boolean = fuConfigs.map(_.hasNoDataWB).reduce(_ || _)
48730cfbc0SXuan Hu  val hasRedirect: Boolean = fuConfigs.map(_.hasRedirect).reduce(_ || _)
49730cfbc0SXuan Hu  val hasPredecode: Boolean = fuConfigs.map(_.hasPredecode).reduce(_ || _)
50730cfbc0SXuan Hu  val exceptionOut: Seq[Int] = fuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted
51730cfbc0SXuan Hu  val hasLoadError: Boolean = fuConfigs.map(_.hasLoadError).reduce(_ || _)
52730cfbc0SXuan Hu  val flushPipe: Boolean = fuConfigs.map(_.flushPipe).reduce(_ || _)
53730cfbc0SXuan Hu  val replayInst: Boolean = fuConfigs.map(_.replayInst).reduce(_ || _)
54730cfbc0SXuan Hu  val trigger: Boolean = fuConfigs.map(_.trigger).reduce(_ || _)
55730cfbc0SXuan Hu  val needExceptionGen: Boolean = exceptionOut.nonEmpty || flushPipe || replayInst || trigger
56730cfbc0SXuan Hu  val needPc: Boolean = fuConfigs.map(_.needPc).reduce(_ || _)
57730cfbc0SXuan Hu  val needSrcFrm: Boolean = fuConfigs.map(_.needSrcFrm).reduce(_ || _)
58730cfbc0SXuan Hu  val needFPUCtrl: Boolean = fuConfigs.map(_.needFPUCtrl).reduce(_ || _)
59b6b11f60SXuan Hu  val needVPUCtrl: Boolean = fuConfigs.map(_.needVecCtrl).reduce(_ || _)
60*39c59369SXuan Hu
61*39c59369SXuan Hu  def rdPregIdxWidth: Int = {
62*39c59369SXuan Hu    this.pregRdDataCfgSet.map(dataCfg => backendParam.getPregParams(dataCfg).addrWidth).fold(0)(_ max _)
63*39c59369SXuan Hu  }
64*39c59369SXuan Hu
65*39c59369SXuan Hu  def wbPregIdxWidth: Int = {
66*39c59369SXuan Hu    this.pregWbDataCfgSet.map(dataCfg => backendParam.getPregParams(dataCfg).addrWidth).fold(0)(_ max _)
67*39c59369SXuan Hu  }
68730cfbc0SXuan Hu
692e0a7dc5Sfdy  val writeIntFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeIntRf)
702e0a7dc5Sfdy  val writeVfFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeFpRf || x.writeVecRf)
712e0a7dc5Sfdy
72bf44d649SXuan Hu  /**
73bf44d649SXuan Hu    * Check if this exu has certain latency
74bf44d649SXuan Hu    */
75bf44d649SXuan Hu  def latencyCertain: Boolean = fuConfigs.map(x => x.latency.latencyVal.nonEmpty).reduce(_ && _)
76bf44d649SXuan Hu  def intLatencyCertain: Boolean = writeIntFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
77bf44d649SXuan Hu  def vfLatencyCertain: Boolean = writeVfFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
782e0a7dc5Sfdy
79bf44d649SXuan Hu  /**
80bf44d649SXuan Hu    * Get mapping from FuType to Latency value.
81bf44d649SXuan Hu    * If [[latencyCertain]] is false, get empty [[Map]]
82bf44d649SXuan Hu    *
83bf44d649SXuan Hu    * @return Map[FuType, Latency]
84bf44d649SXuan Hu    */
85bf44d649SXuan Hu  def fuLatencyMap: Map[Int, Int] = {
86bf44d649SXuan Hu    if (latencyCertain)
87bf44d649SXuan Hu      fuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
88bf44d649SXuan Hu    else
89bf44d649SXuan Hu      Map()
90bf44d649SXuan Hu  }
912e0a7dc5Sfdy
92bf44d649SXuan Hu  /**
93bf44d649SXuan Hu    * Get set of latency of function units.
94bf44d649SXuan Hu    * If [[latencyCertain]] is false, get empty [[Set]]
95bf44d649SXuan Hu    *
96bf44d649SXuan Hu    * @return Set[Latency]
97bf44d649SXuan Hu    */
98bf44d649SXuan Hu  def fuLatancySet: Set[Int] = fuLatencyMap.values.toSet
992e0a7dc5Sfdy
100bf44d649SXuan Hu  def latencyValMax: Int = fuLatancySet.fold(0)(_ max _)
101bf44d649SXuan Hu
102bf44d649SXuan Hu  def intFuLatencyMap: Map[Int, Int] = {
103bf44d649SXuan Hu    if (intLatencyCertain)
104bf44d649SXuan Hu      writeIntFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
105bf44d649SXuan Hu    else
106bf44d649SXuan Hu      Map()
107bf44d649SXuan Hu  }
108bf44d649SXuan Hu
109bf44d649SXuan Hu  def intLatencyValMax: Int = intFuLatencyMap.values.fold(0)(_ max _)
110bf44d649SXuan Hu
111bf44d649SXuan Hu  def vfFuLatencyMap: Map[Int, Int] = {
112bf44d649SXuan Hu    if (vfLatencyCertain)
113bf44d649SXuan Hu      writeVfFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
114bf44d649SXuan Hu    else
115bf44d649SXuan Hu      Map()
116bf44d649SXuan Hu  }
117bf44d649SXuan Hu
118bf44d649SXuan Hu  def vfLatencyValMax: Int = vfFuLatencyMap.values.fold(0)(_ max _)
119bf44d649SXuan Hu
120bf44d649SXuan Hu  /**
121bf44d649SXuan Hu    * Check if this exu has fixed latency
122bf44d649SXuan Hu    */
123bf44d649SXuan Hu  def isFixedLatency: Boolean = {
124bf44d649SXuan Hu    if (latencyCertain)
125bf44d649SXuan Hu      return fuConfigs.map(x => x.latency.latencyVal.get == fuConfigs.head.latency.latencyVal.get).reduce(_ && _)
126bf44d649SXuan Hu    false
127bf44d649SXuan Hu  }
128ea0f92d8Sczw
129730cfbc0SXuan Hu  def hasCSR: Boolean = fuConfigs.map(_.isCsr).reduce(_ || _)
130730cfbc0SXuan Hu
131730cfbc0SXuan Hu  def hasFence: Boolean = fuConfigs.map(_.isFence).reduce(_ || _)
132730cfbc0SXuan Hu
133730cfbc0SXuan Hu  def hasBrhFu = fuConfigs.map(_.fuType == FuType.brh).reduce(_ || _)
134730cfbc0SXuan Hu
135730cfbc0SXuan Hu  def hasJmpFu = fuConfigs.map(_.fuType == FuType.jmp).reduce(_ || _)
136730cfbc0SXuan Hu
137730cfbc0SXuan Hu  def hasLoadFu = fuConfigs.map(_.fuType == FuType.ldu).reduce(_ || _)
138730cfbc0SXuan Hu
1394ee69032SzhanglyGit  def hasVLoadFu = fuConfigs.map(_.fuType == FuType.vldu).reduce(_ || _)
1404ee69032SzhanglyGit
141730cfbc0SXuan Hu  def hasStoreAddrFu = fuConfigs.map(_.name == "sta").reduce(_ || _)
142730cfbc0SXuan Hu
143730cfbc0SXuan Hu  def hasStdFu = fuConfigs.map(_.name == "std").reduce(_ || _)
144730cfbc0SXuan Hu
1454ee69032SzhanglyGit  def hasMemAddrFu = hasLoadFu || hasStoreAddrFu || hasVLoadFu
146730cfbc0SXuan Hu
147da778e6fSXuan Hu  def hasVecFu = fuConfigs.map(x => FuConfig.VecArithFuConfigs.contains(x)).reduce(_ || _)
148da778e6fSXuan Hu
149730cfbc0SXuan Hu  def getSrcDataType(srcIdx: Int): Set[DataConfig] = {
150730cfbc0SXuan Hu    fuConfigs.map(_.getSrcDataType(srcIdx)).reduce(_ ++ _)
151730cfbc0SXuan Hu  }
152730cfbc0SXuan Hu
153730cfbc0SXuan Hu  def immType: Set[UInt] = fuConfigs.map(x => x.immType).reduce(_ ++ _)
154730cfbc0SXuan Hu
155730cfbc0SXuan Hu  def getWBSource: SchedulerType = {
156730cfbc0SXuan Hu    schdType
157730cfbc0SXuan Hu  }
158730cfbc0SXuan Hu
159730cfbc0SXuan Hu  def hasCrossWb: Boolean = {
160730cfbc0SXuan Hu    schdType match {
161730cfbc0SXuan Hu      case IntScheduler() => writeFpRf || writeVecRf
162730cfbc0SXuan Hu      case VfScheduler() => writeIntRf
163730cfbc0SXuan Hu      case _ => false
164730cfbc0SXuan Hu    }
165730cfbc0SXuan Hu  }
166730cfbc0SXuan Hu
167730cfbc0SXuan Hu  def canAccept(fuType: UInt): Bool = {
168730cfbc0SXuan Hu    Cat(fuConfigs.map(_.fuType.U === fuType)).orR
169730cfbc0SXuan Hu  }
170730cfbc0SXuan Hu
171730cfbc0SXuan Hu  def hasUncertainLatency: Boolean = fuConfigs.map(_.latency.latencyVal.isEmpty).reduce(_ || _)
172730cfbc0SXuan Hu
173dd473fffSXuan Hu  def bindBackendParam(param: BackendParams): Unit = {
174dd473fffSXuan Hu    backendParam = param
175dd473fffSXuan Hu  }
176dd473fffSXuan Hu
177d387a573SXuan Hu  def updateIQWakeUpConfigs(cfgs: Seq[WakeUpConfig]) = {
178bf35baadSXuan Hu    this.iqWakeUpSourcePairs = cfgs.filter(_.source.name == this.name)
179bf35baadSXuan Hu    this.iqWakeUpSinkPairs = cfgs.filter(_.sink.name == this.name)
180bf35baadSXuan Hu    if (this.isIQWakeUpSource)
181bf35baadSXuan Hu      require(!this.hasUncertainLatency, s"${this.name} is IQ wake up source, but has UncertainLatency")
182bf35baadSXuan Hu  }
183bf35baadSXuan Hu
184bf35baadSXuan Hu  def updateExuIdx(idx: Int): Unit = {
185bf35baadSXuan Hu    this.exuIdx = idx
186d387a573SXuan Hu  }
187d387a573SXuan Hu
188d387a573SXuan Hu  def isIQWakeUpSource = this.iqWakeUpSourcePairs.nonEmpty
189d387a573SXuan Hu
190d387a573SXuan Hu  def isIQWakeUpSink = this.iqWakeUpSinkPairs.nonEmpty
191d387a573SXuan Hu
192730cfbc0SXuan Hu  def getIntWBPort = {
193730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
194730cfbc0SXuan Hu      case x: IntWB => x
195730cfbc0SXuan Hu    }
196730cfbc0SXuan Hu  }
197730cfbc0SXuan Hu
1980162f462Sczw  def getVfWBPort = {
199730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
2000162f462Sczw      case x: VfWB => x
201730cfbc0SXuan Hu    }
202730cfbc0SXuan Hu  }
203730cfbc0SXuan Hu
204*39c59369SXuan Hu  /**
205*39c59369SXuan Hu    * Get the [[DataConfig]] that this exu need to read
206*39c59369SXuan Hu    */
207*39c59369SXuan Hu  def pregRdDataCfgSet: Set[DataConfig] = {
208*39c59369SXuan Hu    this.rfrPortConfigs.flatten.map(_.getDataConfig).toSet
209*39c59369SXuan Hu  }
210*39c59369SXuan Hu
211*39c59369SXuan Hu  /**
212*39c59369SXuan Hu    * Get the [[DataConfig]] that this exu need to write
213*39c59369SXuan Hu    */
214*39c59369SXuan Hu  def pregWbDataCfgSet: Set[DataConfig] = {
215*39c59369SXuan Hu    this.wbPortConfigs.map(_.dataCfg).toSet
216*39c59369SXuan Hu  }
217*39c59369SXuan Hu
218730cfbc0SXuan Hu  def getRfReadDataCfgSet: Seq[Set[DataConfig]] = {
219730cfbc0SXuan Hu    val fuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuConfigs.map(_.getRfReadDataCfgSet)
220730cfbc0SXuan Hu    val alignedFuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuSrcsCfgSet.map(x => x ++ Seq.fill(numRegSrc - x.length)(Set[DataConfig]()))
221730cfbc0SXuan Hu
222730cfbc0SXuan Hu    val exuSrcsCfgSet = alignedFuSrcsCfgSet.reduce((x, y) => (x zip y).map { case (cfg1, cfg2) => cfg1 union cfg2 })
223730cfbc0SXuan Hu
224730cfbc0SXuan Hu    exuSrcsCfgSet
225730cfbc0SXuan Hu  }
226730cfbc0SXuan Hu
227*39c59369SXuan Hu  /**
228*39c59369SXuan Hu    * Get the [[DataConfig]] mapped indices of source data of exu
229*39c59369SXuan Hu    *
230*39c59369SXuan Hu    * @example
231*39c59369SXuan Hu    * {{{
232*39c59369SXuan Hu    *   fuCfg.srcData = Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData())
233*39c59369SXuan Hu    *   getRfReadSrcIdx(VecData()) = Seq(0, 1, 2)
234*39c59369SXuan Hu    *   getRfReadSrcIdx(MaskSrcData()) = Seq(3)
235*39c59369SXuan Hu    *   getRfReadSrcIdx(VConfigData()) = Seq(4)
236*39c59369SXuan Hu    * }}}
237*39c59369SXuan Hu    * @return Map[DataConfig -> Seq[indices]]
238*39c59369SXuan Hu    */
239*39c59369SXuan Hu  def getRfReadSrcIdx: Map[DataConfig, Seq[Int]] = {
240*39c59369SXuan Hu    val dataCfgs = DataConfig.RegSrcDataSet
241*39c59369SXuan Hu    val rfRdDataCfgSet = this.getRfReadDataCfgSet
242*39c59369SXuan Hu    dataCfgs.toSeq.map { cfg =>
243*39c59369SXuan Hu      (
244*39c59369SXuan Hu        cfg,
245*39c59369SXuan Hu        rfRdDataCfgSet.zipWithIndex.map { case (set, srcIdx) =>
246*39c59369SXuan Hu          if (set.contains(cfg))
247*39c59369SXuan Hu            Option(srcIdx)
248*39c59369SXuan Hu          else
249*39c59369SXuan Hu            None
250*39c59369SXuan Hu        }.filter(_.nonEmpty).map(_.get)
251*39c59369SXuan Hu      )
252*39c59369SXuan Hu    }.toMap
253*39c59369SXuan Hu  }
254*39c59369SXuan Hu
255730cfbc0SXuan Hu  def genExuModule(implicit p: Parameters): ExeUnit = {
256730cfbc0SXuan Hu    new ExeUnit(this)
257730cfbc0SXuan Hu  }
258730cfbc0SXuan Hu
259730cfbc0SXuan Hu  def genExuInputBundle(implicit p: Parameters): ExuInput = {
260730cfbc0SXuan Hu    new ExuInput(this)
261730cfbc0SXuan Hu  }
262730cfbc0SXuan Hu
263730cfbc0SXuan Hu  def genExuOutputBundle(implicit p: Parameters): ExuOutput = {
264730cfbc0SXuan Hu    new ExuOutput(this)
265730cfbc0SXuan Hu  }
2665d2b9cadSXuan Hu
2675d2b9cadSXuan Hu  def genExuBypassBundle(implicit p: Parameters): ExuBypassBundle = {
2685d2b9cadSXuan Hu    new ExuBypassBundle(this)
2695d2b9cadSXuan Hu  }
270730cfbc0SXuan Hu}
271