xref: /XiangShan/src/main/scala/xiangshan/backend/exu/ExeUnitParams.scala (revision 0ed0e482b4d85da1fe7dcd24705d25559036f63f)
1730cfbc0SXuan Hupackage xiangshan.backend.exu
2730cfbc0SXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
6dd473fffSXuan Huimport xiangshan.backend.BackendParams
739c59369SXuan Huimport xiangshan.backend.Bundles.{ExuBypassBundle, ExuInput, ExuOutput}
8730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig.DataConfig
9730cfbc0SXuan Huimport xiangshan.backend.datapath.RdConfig._
10de8bd1d0Ssinsanctionimport xiangshan.backend.datapath.WbConfig._
1139c59369SXuan Huimport xiangshan.backend.datapath.{DataConfig, WakeUpConfig}
12730cfbc0SXuan Huimport xiangshan.backend.fu.{FuConfig, FuType}
132e49ee76Ssinsanctionimport xiangshan.backend.issue.{IssueBlockParams, SchedulerType, IntScheduler, VfScheduler, MemScheduler}
144c5a0d77Sxiaofeibao-xjtuimport scala.collection.mutable
15730cfbc0SXuan Hu
16730cfbc0SXuan Hucase class ExeUnitParams(
1708017d75SXuan Hu  name          : String,
18730cfbc0SXuan Hu  fuConfigs     : Seq[FuConfig],
1939c59369SXuan Hu  wbPortConfigs : Seq[PregWB],
20730cfbc0SXuan Hu  rfrPortConfigs: Seq[Seq[RdConfig]],
214c5a0d77Sxiaofeibao-xjtu  copyWakeupOut: Boolean = false,
220c7ebb58Sxiaofeibao-xjtu  copyDistance: Int = 1,
23670870b3SXuan Hu  fakeUnit      : Boolean = false,
24730cfbc0SXuan Hu)(
25730cfbc0SXuan Hu  implicit
26730cfbc0SXuan Hu  val schdType: SchedulerType,
27730cfbc0SXuan Hu) {
28d387a573SXuan Hu  // calculated configs
29d387a573SXuan Hu  var iqWakeUpSourcePairs: Seq[WakeUpConfig] = Seq()
30d387a573SXuan Hu  var iqWakeUpSinkPairs: Seq[WakeUpConfig] = Seq()
31e600b1ddSxiaofeibao-xjtu  var needLoadDependency: Boolean = false
32bf35baadSXuan Hu  // used in bypass to select data of exu output
33bf35baadSXuan Hu  var exuIdx: Int = -1
34dd473fffSXuan Hu  var backendParam: BackendParams = null
35d387a573SXuan Hu
36730cfbc0SXuan Hu  val numIntSrc: Int = fuConfigs.map(_.numIntSrc).max
37730cfbc0SXuan Hu  val numFpSrc: Int = fuConfigs.map(_.numFpSrc).max
38730cfbc0SXuan Hu  val numVecSrc: Int = fuConfigs.map(_.numVecSrc).max
39730cfbc0SXuan Hu  val numVfSrc: Int = fuConfigs.map(_.numVfSrc).max
40de8bd1d0Ssinsanction  val numV0Src: Int = fuConfigs.map(_.numV0Src).max
41de8bd1d0Ssinsanction  val numVlSrc: Int = fuConfigs.map(_.numVlSrc).max
42730cfbc0SXuan Hu  val numRegSrc: Int = fuConfigs.map(_.numRegSrc).max
43730cfbc0SXuan Hu  val numSrc: Int = fuConfigs.map(_.numSrc).max
442d12882cSxiaofeibao  val destDataBitsMax: Int = fuConfigs.map(_.destDataBits).max
452d12882cSxiaofeibao  val srcDataBitsMax: Int = fuConfigs.map(x => x.srcDataBits.getOrElse(x.destDataBits)).max
46730cfbc0SXuan Hu  val readIntRf: Boolean = numIntSrc > 0
47730cfbc0SXuan Hu  val readFpRf: Boolean = numFpSrc > 0
48730cfbc0SXuan Hu  val readVecRf: Boolean = numVecSrc > 0
494fa640e4Ssinsanction  val readVfRf: Boolean = numVfSrc > 0
50e600b1ddSxiaofeibao-xjtu  val readVlRf: Boolean = numVlSrc > 0
51730cfbc0SXuan Hu  val writeIntRf: Boolean = fuConfigs.map(_.writeIntRf).reduce(_ || _)
52730cfbc0SXuan Hu  val writeFpRf: Boolean = fuConfigs.map(_.writeFpRf).reduce(_ || _)
53730cfbc0SXuan Hu  val writeVecRf: Boolean = fuConfigs.map(_.writeVecRf).reduce(_ || _)
5445d40ce7Ssinsanction  val writeV0Rf: Boolean = fuConfigs.map(_.writeV0Rf).reduce(_ || _)
5545d40ce7Ssinsanction  val writeVlRf: Boolean = fuConfigs.map(_.writeVlRf).reduce(_ || _)
565edcc45fSHaojin Tang  val needIntWen: Boolean = fuConfigs.map(_.needIntWen).reduce(_ || _)
575edcc45fSHaojin Tang  val needFpWen: Boolean = fuConfigs.map(_.needFpWen).reduce(_ || _)
585edcc45fSHaojin Tang  val needVecWen: Boolean = fuConfigs.map(_.needVecWen).reduce(_ || _)
59de8bd1d0Ssinsanction  val needV0Wen: Boolean = fuConfigs.map(_.needV0Wen).reduce(_ || _)
60de8bd1d0Ssinsanction  val needVlWen: Boolean = fuConfigs.map(_.needVlWen).reduce(_ || _)
61c38df446SzhanglyGit  val needOg2: Boolean = fuConfigs.map(_.needOg2).reduce(_ || _)
6260f0c5aeSxiaofeibao  val writeVfRf: Boolean = writeVecRf
63730cfbc0SXuan Hu  val writeFflags: Boolean = fuConfigs.map(_.writeFflags).reduce(_ || _)
64a8db15d8Sfdy  val writeVxsat: Boolean = fuConfigs.map(_.writeVxsat).reduce(_ || _)
65c1e19666Sxiaofeibao-xjtu  val hasNoDataWB: Boolean = fuConfigs.map(_.hasNoDataWB).reduce(_ && _)
66730cfbc0SXuan Hu  val hasRedirect: Boolean = fuConfigs.map(_.hasRedirect).reduce(_ || _)
67730cfbc0SXuan Hu  val hasPredecode: Boolean = fuConfigs.map(_.hasPredecode).reduce(_ || _)
68730cfbc0SXuan Hu  val exceptionOut: Seq[Int] = fuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted
69730cfbc0SXuan Hu  val hasLoadError: Boolean = fuConfigs.map(_.hasLoadError).reduce(_ || _)
70730cfbc0SXuan Hu  val flushPipe: Boolean = fuConfigs.map(_.flushPipe).reduce(_ || _)
71730cfbc0SXuan Hu  val replayInst: Boolean = fuConfigs.map(_.replayInst).reduce(_ || _)
72730cfbc0SXuan Hu  val trigger: Boolean = fuConfigs.map(_.trigger).reduce(_ || _)
73730cfbc0SXuan Hu  val needExceptionGen: Boolean = exceptionOut.nonEmpty || flushPipe || replayInst || trigger
74730cfbc0SXuan Hu  val needPc: Boolean = fuConfigs.map(_.needPc).reduce(_ || _)
759d8d7860SXuan Hu  val needTarget: Boolean = fuConfigs.map(_.needTargetPc).reduce(_ || _)
769d8d7860SXuan Hu  val needPdInfo: Boolean = fuConfigs.map(_.needPdInfo).reduce(_ || _)
77730cfbc0SXuan Hu  val needSrcFrm: Boolean = fuConfigs.map(_.needSrcFrm).reduce(_ || _)
7817985fbbSZiyue Zhang  val needSrcVxrm: Boolean = fuConfigs.map(_.needSrcVxrm).reduce(_ || _)
79730cfbc0SXuan Hu  val needFPUCtrl: Boolean = fuConfigs.map(_.needFPUCtrl).reduce(_ || _)
80b6b11f60SXuan Hu  val needVPUCtrl: Boolean = fuConfigs.map(_.needVecCtrl).reduce(_ || _)
81b8db7211Sxiaofeibao  val writeVConfig: Boolean = fuConfigs.map(_.writeVlRf).reduce(_ || _)
827e4f0b19SZiyue-Zhang  val writeVType: Boolean = fuConfigs.map(_.writeVType).reduce(_ || _)
8385a8d7caSZehao Liu  val needCriticalErrors: Boolean = fuConfigs.map(_.needCriticalErrors).reduce(_ || _)
84bcf0356aSXuan Hu  val isHighestWBPriority: Boolean = wbPortConfigs.forall(_.priority == 0)
8539c59369SXuan Hu
862e49ee76Ssinsanction  val isIntExeUnit: Boolean = schdType.isInstanceOf[IntScheduler]
872e49ee76Ssinsanction  val isVfExeUnit: Boolean = schdType.isInstanceOf[VfScheduler]
882e49ee76Ssinsanction  val isMemExeUnit: Boolean = schdType.isInstanceOf[MemScheduler]
892e49ee76Ssinsanction
90f8b278aaSsinsanction  def needReadRegCache: Boolean = isIntExeUnit || isMemExeUnit && readIntRf
91f8b278aaSsinsanction  def needWriteRegCache: Boolean = isIntExeUnit && isIQWakeUpSource || isMemExeUnit && isIQWakeUpSource && readIntRf
92ae4984bfSsinsanction
93*0ed0e482SGuanghui Cheng  def numCopySrc: Int = fuConfigs.map(x => if(x.srcNeedCopy) 1 else 0).reduce(_ + _)
94*0ed0e482SGuanghui Cheng  def idxCopySrc: Seq[Int] = (0 until fuConfigs.length).map { idx =>
95*0ed0e482SGuanghui Cheng    fuConfigs.take(idx + 1).map(x => if(x.srcNeedCopy) 1 else 0).reduce(_ + _) - 1
96*0ed0e482SGuanghui Cheng  }
97*0ed0e482SGuanghui Cheng
98618b89e6Slewislzh  // exu writeback: 0 normalout; 1 intout; 2 fpout; 3 vecout
99618b89e6Slewislzh  val wbNeedIntWen : Boolean = writeIntRf && !isMemExeUnit
100618b89e6Slewislzh  val wbNeedFpWen  : Boolean = writeFpRf  && !isMemExeUnit
101618b89e6Slewislzh  val wbNeedVecWen : Boolean = writeVecRf && !isMemExeUnit
102618b89e6Slewislzh  val wbNeedV0Wen  : Boolean = writeV0Rf  && !isMemExeUnit
103618b89e6Slewislzh  val wbNeedVlWen  : Boolean = writeVlRf  && !isMemExeUnit
104618b89e6Slewislzh  val wbPathNum: Int = Seq(wbNeedIntWen, wbNeedFpWen, wbNeedVecWen, wbNeedV0Wen, wbNeedVlWen).count(_ == true) + 1
105618b89e6Slewislzh  val wbNeeds = Seq(
106618b89e6Slewislzh    ("int", wbNeedIntWen),
107618b89e6Slewislzh    ("fp", wbNeedFpWen),
108618b89e6Slewislzh    ("vec", wbNeedVecWen),
109618b89e6Slewislzh    ("v0", wbNeedV0Wen),
110618b89e6Slewislzh    ("vl", wbNeedVlWen)
111618b89e6Slewislzh  )
112618b89e6Slewislzh  val wbIndexeds = wbNeeds.filter(_._2).zipWithIndex.map {
113618b89e6Slewislzh    case ((label, _), index) => (label, index + 1)
114618b89e6Slewislzh  }.toMap
115618b89e6Slewislzh  val wbIntIndex: Int = wbIndexeds.getOrElse("int", 0)
116618b89e6Slewislzh  val wbFpIndex : Int = wbIndexeds.getOrElse("fp",  0)
117618b89e6Slewislzh  val wbVecIndex: Int = wbIndexeds.getOrElse("vec", 0)
118618b89e6Slewislzh  val wbV0Index : Int = wbIndexeds.getOrElse("v0" , 0)
119618b89e6Slewislzh  val wbVlIndex : Int = wbIndexeds.getOrElse("vl" , 0)
120618b89e6Slewislzh  val wbIndex: Seq[Int] = Seq(wbIntIndex, wbFpIndex, wbVecIndex, wbV0Index, wbVlIndex)
121618b89e6Slewislzh
122618b89e6Slewislzh
1234c5a0d77Sxiaofeibao-xjtu  def copyNum: Int = {
1244c5a0d77Sxiaofeibao-xjtu    val setIQ = mutable.Set[IssueBlockParams]()
1254c5a0d77Sxiaofeibao-xjtu    iqWakeUpSourcePairs.map(_.sink).foreach{ wakeupSink =>
1264c5a0d77Sxiaofeibao-xjtu      backendParam.allIssueParams.map{ issueParams =>
1274c5a0d77Sxiaofeibao-xjtu        if (issueParams.exuBlockParams.contains(wakeupSink.getExuParam(backendParam.allExuParams))) {
1284c5a0d77Sxiaofeibao-xjtu          setIQ.add(issueParams)
1294c5a0d77Sxiaofeibao-xjtu        }
1304c5a0d77Sxiaofeibao-xjtu      }
1314c5a0d77Sxiaofeibao-xjtu    }
1324c5a0d77Sxiaofeibao-xjtu    println(s"[Backend] exuIdx ${exuIdx} numWakeupIQ ${setIQ.size}")
13371dbd663Sxiaofeibao-xjtu    1 + setIQ.size / copyDistance
1344c5a0d77Sxiaofeibao-xjtu  }
13539c59369SXuan Hu  def rdPregIdxWidth: Int = {
13639c59369SXuan Hu    this.pregRdDataCfgSet.map(dataCfg => backendParam.getPregParams(dataCfg).addrWidth).fold(0)(_ max _)
13739c59369SXuan Hu  }
13839c59369SXuan Hu
13939c59369SXuan Hu  def wbPregIdxWidth: Int = {
14039c59369SXuan Hu    this.pregWbDataCfgSet.map(dataCfg => backendParam.getPregParams(dataCfg).addrWidth).fold(0)(_ max _)
14139c59369SXuan Hu  }
142730cfbc0SXuan Hu
1432e0a7dc5Sfdy  val writeIntFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeIntRf)
14460f0c5aeSxiaofeibao  val writeFpFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeFpRf)
14560f0c5aeSxiaofeibao  val writeVfFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeVecRf)
1462aa3a761Ssinsanction  val writeV0FuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeV0Rf)
1472aa3a761Ssinsanction  val writeVlFuConfigs: Seq[FuConfig] = fuConfigs.filter(x => x.writeVlRf)
1482e0a7dc5Sfdy
149bf44d649SXuan Hu  /**
150bf44d649SXuan Hu    * Check if this exu has certain latency
151bf44d649SXuan Hu    */
152bf44d649SXuan Hu  def latencyCertain: Boolean = fuConfigs.map(x => x.latency.latencyVal.nonEmpty).reduce(_ && _)
153bf44d649SXuan Hu  def intLatencyCertain: Boolean = writeIntFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
15460f0c5aeSxiaofeibao  def fpLatencyCertain: Boolean = writeFpFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
155bf44d649SXuan Hu  def vfLatencyCertain: Boolean = writeVfFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
1562aa3a761Ssinsanction  def v0LatencyCertain: Boolean = writeV0FuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
1572aa3a761Ssinsanction  def vlLatencyCertain: Boolean = writeVlFuConfigs.forall(x => x.latency.latencyVal.nonEmpty)
158f9f1abd7SXuan Hu  // only load use it
159f9f1abd7SXuan Hu  def hasUncertainLatencyVal: Boolean = fuConfigs.map(x => x.latency.uncertainLatencyVal.nonEmpty).reduce(_ || _)
1602e0a7dc5Sfdy
161bf44d649SXuan Hu  /**
162bf44d649SXuan Hu    * Get mapping from FuType to Latency value.
16323c67001SHaojin Tang    * If both [[latencyCertain]] and [[hasUncertainLatencyVal]] are false, get empty [[Map]]
164bf44d649SXuan Hu    *
165239413e5SXuan Hu    * @return Map[ [[BigInt]], Latency]
166bf44d649SXuan Hu    */
167239413e5SXuan Hu  def fuLatencyMap: Map[FuType.OHType, Int] = {
168bf44d649SXuan Hu    if (latencyCertain)
169c38df446SzhanglyGit      if(needOg2) fuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 1)).toMap else fuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
17023c67001SHaojin Tang    else if (hasUncertainLatencyVal)
171f9f1abd7SXuan Hu      fuConfigs.map(x => (x.fuType, x.latency.uncertainLatencyVal)).toMap.filter(_._2.nonEmpty).map(x => (x._1, x._2.get))
172bf44d649SXuan Hu    else
173bf44d649SXuan Hu      Map()
174bf44d649SXuan Hu  }
1756fa1007bSxiaofeibao-xjtu  def wakeUpFuLatencyMap: Map[FuType.OHType, Int] = {
1766fa1007bSxiaofeibao-xjtu    if (latencyCertain)
1776fa1007bSxiaofeibao-xjtu      fuConfigs.filterNot(_.hasNoDataWB).map(x => (x.fuType, x.latency.latencyVal.get)).toMap
1786fa1007bSxiaofeibao-xjtu    else if (hasUncertainLatencyVal)
1796fa1007bSxiaofeibao-xjtu      fuConfigs.filterNot(_.hasNoDataWB).map(x => (x.fuType, x.latency.uncertainLatencyVal.get)).toMap
1806fa1007bSxiaofeibao-xjtu    else
1816fa1007bSxiaofeibao-xjtu      Map()
1826fa1007bSxiaofeibao-xjtu  }
1832e0a7dc5Sfdy
184bf44d649SXuan Hu  /**
185bf44d649SXuan Hu    * Get set of latency of function units.
18623c67001SHaojin Tang    * If both [[latencyCertain]] and [[hasUncertainLatencyVal]] are false, get empty [[Set]]
187bf44d649SXuan Hu    *
188bf44d649SXuan Hu    * @return Set[Latency]
189bf44d649SXuan Hu    */
190bf44d649SXuan Hu  def fuLatancySet: Set[Int] = fuLatencyMap.values.toSet
1912e0a7dc5Sfdy
1926fa1007bSxiaofeibao-xjtu  def wakeUpFuLatancySet: Set[Int] = wakeUpFuLatencyMap.values.toSet
1936fa1007bSxiaofeibao-xjtu
194bf44d649SXuan Hu  def latencyValMax: Int = fuLatancySet.fold(0)(_ max _)
195bf44d649SXuan Hu
196239413e5SXuan Hu  def intFuLatencyMap: Map[FuType.OHType, Int] = {
1972e49ee76Ssinsanction    if (intLatencyCertain) {
1982e49ee76Ssinsanction      if (isVfExeUnit) {
1992e49ee76Ssinsanction        // vf exe unit writing back to int regfile should delay 1 cycle
200c38df446SzhanglyGit        // vf exe unit need og2 --> delay 1 cycle
201c38df446SzhanglyGit        writeIntFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 2)).toMap
2022e49ee76Ssinsanction      } else {
203bf44d649SXuan Hu        writeIntFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
2042e49ee76Ssinsanction      }
2052e49ee76Ssinsanction    }
206bf44d649SXuan Hu    else
207bf44d649SXuan Hu      Map()
208bf44d649SXuan Hu  }
209bf44d649SXuan Hu
210bf44d649SXuan Hu  def intLatencyValMax: Int = intFuLatencyMap.values.fold(0)(_ max _)
211bf44d649SXuan Hu
21260f0c5aeSxiaofeibao  def fpFuLatencyMap: Map[FuType.OHType, Int] = {
21360f0c5aeSxiaofeibao    if (fpLatencyCertain)
2149d9be651SsinceforYy      if (needOg2) writeFpFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 1)).toMap else writeFpFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
21560f0c5aeSxiaofeibao    else
21660f0c5aeSxiaofeibao      Map()
21760f0c5aeSxiaofeibao  }
21860f0c5aeSxiaofeibao
21960f0c5aeSxiaofeibao  def fpLatencyValMax: Int = fpFuLatencyMap.values.fold(0)(_ max _)
22060f0c5aeSxiaofeibao
221239413e5SXuan Hu  def vfFuLatencyMap: Map[FuType.OHType, Int] = {
222bf44d649SXuan Hu    if (vfLatencyCertain)
223c38df446SzhanglyGit      if(needOg2) writeVfFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 1)).toMap else writeVfFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
224bf44d649SXuan Hu    else
225bf44d649SXuan Hu      Map()
226bf44d649SXuan Hu  }
227bf44d649SXuan Hu
228bf44d649SXuan Hu  def vfLatencyValMax: Int = vfFuLatencyMap.values.fold(0)(_ max _)
229bf44d649SXuan Hu
2302aa3a761Ssinsanction  def v0FuLatencyMap: Map[FuType.OHType, Int] = {
2312aa3a761Ssinsanction    if (v0LatencyCertain)
2322aa3a761Ssinsanction      if(needOg2) writeV0FuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 1)).toMap else writeV0FuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
2332aa3a761Ssinsanction    else
2342aa3a761Ssinsanction      Map()
2352aa3a761Ssinsanction  }
2362aa3a761Ssinsanction
2372aa3a761Ssinsanction  def v0LatencyValMax: Int = v0FuLatencyMap.values.fold(0)(_ max _)
2382aa3a761Ssinsanction
2392aa3a761Ssinsanction  def vlFuLatencyMap: Map[FuType.OHType, Int] = {
2402aa3a761Ssinsanction    if (vlLatencyCertain)
2412aa3a761Ssinsanction      if(needOg2) writeVlFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get + 1)).toMap else writeVlFuConfigs.map(x => (x.fuType, x.latency.latencyVal.get)).toMap
2422aa3a761Ssinsanction    else
2432aa3a761Ssinsanction      Map()
2442aa3a761Ssinsanction  }
2452aa3a761Ssinsanction
2462aa3a761Ssinsanction  def vlLatencyValMax: Int = vlFuLatencyMap.values.fold(0)(_ max _)
2472aa3a761Ssinsanction
248bf44d649SXuan Hu  /**
249bf44d649SXuan Hu    * Check if this exu has fixed latency
250bf44d649SXuan Hu    */
251bf44d649SXuan Hu  def isFixedLatency: Boolean = {
252bf44d649SXuan Hu    if (latencyCertain)
253bf44d649SXuan Hu      return fuConfigs.map(x => x.latency.latencyVal.get == fuConfigs.head.latency.latencyVal.get).reduce(_ && _)
254bf44d649SXuan Hu    false
255bf44d649SXuan Hu  }
256ea0f92d8Sczw
257730cfbc0SXuan Hu  def hasCSR: Boolean = fuConfigs.map(_.isCsr).reduce(_ || _)
258730cfbc0SXuan Hu
259730cfbc0SXuan Hu  def hasFence: Boolean = fuConfigs.map(_.isFence).reduce(_ || _)
260730cfbc0SXuan Hu
261730cfbc0SXuan Hu  def hasBrhFu = fuConfigs.map(_.fuType == FuType.brh).reduce(_ || _)
262730cfbc0SXuan Hu
2630a7d1d5cSxiaofeibao  def hasAluFu = fuConfigs.map(_.fuType == FuType.alu).reduce(_ || _)
2640a7d1d5cSxiaofeibao
265618b89e6Slewislzh  def hasi2vFu = fuConfigs.map(_.fuType == FuType.i2v).reduce(_ || _)
266618b89e6Slewislzh
267730cfbc0SXuan Hu  def hasJmpFu = fuConfigs.map(_.fuType == FuType.jmp).reduce(_ || _)
268730cfbc0SXuan Hu
269670870b3SXuan Hu  def hasLoadFu = fuConfigs.map(_.name == "ldu").reduce(_ || _)
270730cfbc0SXuan Hu
2714ee69032SzhanglyGit  def hasVLoadFu = fuConfigs.map(_.fuType == FuType.vldu).reduce(_ || _)
2724ee69032SzhanglyGit
27320a5248fSzhanglinjuan  def hasVStoreFu = fuConfigs.map(_.fuType == FuType.vstu).reduce(_ || _)
27420a5248fSzhanglinjuan
2756dbb4e08SXuan Hu  def hasVecLsFu = fuConfigs.map(x => FuType.FuTypeOrR(x.fuType, Seq(FuType.vldu, FuType.vstu))).reduce(_ || _)
2766dbb4e08SXuan Hu
277730cfbc0SXuan Hu  def hasStoreAddrFu = fuConfigs.map(_.name == "sta").reduce(_ || _)
278730cfbc0SXuan Hu
279730cfbc0SXuan Hu  def hasStdFu = fuConfigs.map(_.name == "std").reduce(_ || _)
280730cfbc0SXuan Hu
28120a5248fSzhanglinjuan  def hasMemAddrFu = hasLoadFu || hasStoreAddrFu || hasVLoadFu || hasHyldaFu || hasHystaFu || hasVLoadFu || hasVStoreFu
282730cfbc0SXuan Hu
283670870b3SXuan Hu  def hasHyldaFu = fuConfigs.map(_.name == "hylda").reduce(_ || _)
284670870b3SXuan Hu
285670870b3SXuan Hu  def hasHystaFu = fuConfigs.map(_.name == "hysta").reduce(_ || _)
286b133b458SXuan Hu
287272ec6b1SHaojin Tang  def hasLoadExu = hasLoadFu || hasHyldaFu
288272ec6b1SHaojin Tang
289272ec6b1SHaojin Tang  def hasStoreAddrExu = hasStoreAddrFu || hasHystaFu
290272ec6b1SHaojin Tang
291da778e6fSXuan Hu  def hasVecFu = fuConfigs.map(x => FuConfig.VecArithFuConfigs.contains(x)).reduce(_ || _)
292da778e6fSXuan Hu
293618b89e6Slewislzh  def CanCompress = !hasBrhFu || (hasBrhFu && hasi2vFu)
294618b89e6Slewislzh
295730cfbc0SXuan Hu  def getSrcDataType(srcIdx: Int): Set[DataConfig] = {
296730cfbc0SXuan Hu    fuConfigs.map(_.getSrcDataType(srcIdx)).reduce(_ ++ _)
297730cfbc0SXuan Hu  }
298730cfbc0SXuan Hu
299730cfbc0SXuan Hu  def immType: Set[UInt] = fuConfigs.map(x => x.immType).reduce(_ ++ _)
300730cfbc0SXuan Hu
301730cfbc0SXuan Hu  def getWBSource: SchedulerType = {
302730cfbc0SXuan Hu    schdType
303730cfbc0SXuan Hu  }
304730cfbc0SXuan Hu
305730cfbc0SXuan Hu  def hasCrossWb: Boolean = {
306730cfbc0SXuan Hu    schdType match {
307730cfbc0SXuan Hu      case IntScheduler() => writeFpRf || writeVecRf
308730cfbc0SXuan Hu      case VfScheduler() => writeIntRf
309730cfbc0SXuan Hu      case _ => false
310730cfbc0SXuan Hu    }
311730cfbc0SXuan Hu  }
312730cfbc0SXuan Hu
313730cfbc0SXuan Hu  def canAccept(fuType: UInt): Bool = {
314730cfbc0SXuan Hu    Cat(fuConfigs.map(_.fuType.U === fuType)).orR
315730cfbc0SXuan Hu  }
316730cfbc0SXuan Hu
317730cfbc0SXuan Hu  def hasUncertainLatency: Boolean = fuConfigs.map(_.latency.latencyVal.isEmpty).reduce(_ || _)
318730cfbc0SXuan Hu
319dd473fffSXuan Hu  def bindBackendParam(param: BackendParams): Unit = {
320dd473fffSXuan Hu    backendParam = param
321dd473fffSXuan Hu  }
322dd473fffSXuan Hu
323d387a573SXuan Hu  def updateIQWakeUpConfigs(cfgs: Seq[WakeUpConfig]) = {
324bf35baadSXuan Hu    this.iqWakeUpSourcePairs = cfgs.filter(_.source.name == this.name)
325bf35baadSXuan Hu    this.iqWakeUpSinkPairs = cfgs.filter(_.sink.name == this.name)
326b133b458SXuan Hu    if (this.isIQWakeUpSource) {
327670870b3SXuan Hu      require(!this.hasUncertainLatency || hasLoadFu || hasHyldaFu, s"${this.name} is a not-LDU IQ wake up source , but has UncertainLatency")
328bf35baadSXuan Hu    }
329e600b1ddSxiaofeibao-xjtu    val loadWakeUpSourcePairs = cfgs.filter(x => x.source.getExuParam(backendParam.allExuParams).hasLoadFu || x.source.getExuParam(backendParam.allExuParams).hasHyldaFu)
330e600b1ddSxiaofeibao-xjtu    val wakeUpByLoadNames = loadWakeUpSourcePairs.map(_.sink.name).toSet
331e600b1ddSxiaofeibao-xjtu    val thisWakeUpByNames = iqWakeUpSinkPairs.map(_.source.name).toSet
332e600b1ddSxiaofeibao-xjtu    this.needLoadDependency = !(wakeUpByLoadNames & thisWakeUpByNames).isEmpty
333e600b1ddSxiaofeibao-xjtu    println(s"${this.name}: needLoadDependency is ${this.needLoadDependency}")
334b133b458SXuan Hu  }
335bf35baadSXuan Hu
336bf35baadSXuan Hu  def updateExuIdx(idx: Int): Unit = {
337bf35baadSXuan Hu    this.exuIdx = idx
338d387a573SXuan Hu  }
339d387a573SXuan Hu
340d387a573SXuan Hu  def isIQWakeUpSource = this.iqWakeUpSourcePairs.nonEmpty
341d387a573SXuan Hu
342d387a573SXuan Hu  def isIQWakeUpSink = this.iqWakeUpSinkPairs.nonEmpty
343d387a573SXuan Hu
344f57d73d6Ssinsanction  def numWakeupFromIQ = this.iqWakeUpSinkPairs.size
345f57d73d6Ssinsanction
346730cfbc0SXuan Hu  def getIntWBPort = {
347730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
348730cfbc0SXuan Hu      case x: IntWB => x
349730cfbc0SXuan Hu    }
350730cfbc0SXuan Hu  }
351730cfbc0SXuan Hu
35260f0c5aeSxiaofeibao  def getFpWBPort = {
35360f0c5aeSxiaofeibao    wbPortConfigs.collectFirst {
35460f0c5aeSxiaofeibao      case x: FpWB => x
35560f0c5aeSxiaofeibao    }
35660f0c5aeSxiaofeibao  }
35760f0c5aeSxiaofeibao
3580162f462Sczw  def getVfWBPort = {
359730cfbc0SXuan Hu    wbPortConfigs.collectFirst {
3600162f462Sczw      case x: VfWB => x
361730cfbc0SXuan Hu    }
362730cfbc0SXuan Hu  }
363730cfbc0SXuan Hu
364de8bd1d0Ssinsanction  def getV0WBPort = {
365de8bd1d0Ssinsanction    wbPortConfigs.collectFirst {
366de8bd1d0Ssinsanction      case x: V0WB => x
367de8bd1d0Ssinsanction    }
368de8bd1d0Ssinsanction  }
369de8bd1d0Ssinsanction
370de8bd1d0Ssinsanction  def getVlWBPort = {
371de8bd1d0Ssinsanction    wbPortConfigs.collectFirst {
372de8bd1d0Ssinsanction      case x: VlWB => x
373de8bd1d0Ssinsanction    }
374de8bd1d0Ssinsanction  }
375de8bd1d0Ssinsanction
37639c59369SXuan Hu  /**
37739c59369SXuan Hu    * Get the [[DataConfig]] that this exu need to read
37839c59369SXuan Hu    */
37939c59369SXuan Hu  def pregRdDataCfgSet: Set[DataConfig] = {
38039c59369SXuan Hu    this.rfrPortConfigs.flatten.map(_.getDataConfig).toSet
38139c59369SXuan Hu  }
38239c59369SXuan Hu
38339c59369SXuan Hu  /**
38439c59369SXuan Hu    * Get the [[DataConfig]] that this exu need to write
38539c59369SXuan Hu    */
38639c59369SXuan Hu  def pregWbDataCfgSet: Set[DataConfig] = {
38739c59369SXuan Hu    this.wbPortConfigs.map(_.dataCfg).toSet
38839c59369SXuan Hu  }
38939c59369SXuan Hu
390730cfbc0SXuan Hu  def getRfReadDataCfgSet: Seq[Set[DataConfig]] = {
391730cfbc0SXuan Hu    val fuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuConfigs.map(_.getRfReadDataCfgSet)
392730cfbc0SXuan Hu    val alignedFuSrcsCfgSet: Seq[Seq[Set[DataConfig]]] = fuSrcsCfgSet.map(x => x ++ Seq.fill(numRegSrc - x.length)(Set[DataConfig]()))
393730cfbc0SXuan Hu
394730cfbc0SXuan Hu    val exuSrcsCfgSet = alignedFuSrcsCfgSet.reduce((x, y) => (x zip y).map { case (cfg1, cfg2) => cfg1 union cfg2 })
395730cfbc0SXuan Hu
396730cfbc0SXuan Hu    exuSrcsCfgSet
397730cfbc0SXuan Hu  }
398730cfbc0SXuan Hu
39939c59369SXuan Hu  /**
40039c59369SXuan Hu    * Get the [[DataConfig]] mapped indices of source data of exu
40139c59369SXuan Hu    *
40239c59369SXuan Hu    * @example
40339c59369SXuan Hu    * {{{
404e4e52e7dSsinsanction    *   fuCfg.srcData = Seq(VecData(), VecData(), VecData(), V0Data(), VlData())
40539c59369SXuan Hu    *   getRfReadSrcIdx(VecData()) = Seq(0, 1, 2)
406e4e52e7dSsinsanction    *   getRfReadSrcIdx(V0Data()) = Seq(3)
407e4e52e7dSsinsanction    *   getRfReadSrcIdx(VlData()) = Seq(4)
40839c59369SXuan Hu    * }}}
40939c59369SXuan Hu    * @return Map[DataConfig -> Seq[indices]]
41039c59369SXuan Hu    */
41139c59369SXuan Hu  def getRfReadSrcIdx: Map[DataConfig, Seq[Int]] = {
41239c59369SXuan Hu    val dataCfgs = DataConfig.RegSrcDataSet
41339c59369SXuan Hu    val rfRdDataCfgSet = this.getRfReadDataCfgSet
41439c59369SXuan Hu    dataCfgs.toSeq.map { cfg =>
41539c59369SXuan Hu      (
41639c59369SXuan Hu        cfg,
41739c59369SXuan Hu        rfRdDataCfgSet.zipWithIndex.map { case (set, srcIdx) =>
41839c59369SXuan Hu          if (set.contains(cfg))
41939c59369SXuan Hu            Option(srcIdx)
42039c59369SXuan Hu          else
42139c59369SXuan Hu            None
42239c59369SXuan Hu        }.filter(_.nonEmpty).map(_.get)
42339c59369SXuan Hu      )
42439c59369SXuan Hu    }.toMap
42539c59369SXuan Hu  }
42639c59369SXuan Hu
427730cfbc0SXuan Hu  def genExuModule(implicit p: Parameters): ExeUnit = {
428730cfbc0SXuan Hu    new ExeUnit(this)
429730cfbc0SXuan Hu  }
430730cfbc0SXuan Hu
431730cfbc0SXuan Hu  def genExuInputBundle(implicit p: Parameters): ExuInput = {
432730cfbc0SXuan Hu    new ExuInput(this)
433730cfbc0SXuan Hu  }
434730cfbc0SXuan Hu
435*0ed0e482SGuanghui Cheng  def genExuInputCopySrcBundle(implicit p: Parameters): ExuInput = {
436*0ed0e482SGuanghui Cheng    new ExuInput(this, hasCopySrc = true)
437*0ed0e482SGuanghui Cheng  }
438*0ed0e482SGuanghui Cheng
439730cfbc0SXuan Hu  def genExuOutputBundle(implicit p: Parameters): ExuOutput = {
440730cfbc0SXuan Hu    new ExuOutput(this)
441730cfbc0SXuan Hu  }
4425d2b9cadSXuan Hu
4435d2b9cadSXuan Hu  def genExuBypassBundle(implicit p: Parameters): ExuBypassBundle = {
4445d2b9cadSXuan Hu    new ExuBypassBundle(this)
4455d2b9cadSXuan Hu  }
446730cfbc0SXuan Hu}
447