xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FuConfig.scala (revision 39be24bce97876599cf209a1e8a822f27651258c)
1package xiangshan.backend.fu
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import utils.EnumUtils.OHEnumeration
6import xiangshan.ExceptionNO._
7import xiangshan.SelImm
8import xiangshan.backend.Std
9import xiangshan.backend.fu.fpu.{IntToFP, IntFPToVec}
10import xiangshan.backend.fu.wrapper._
11import xiangshan.backend.Bundles.ExuInput
12import xiangshan.backend.datapath.DataConfig._
13
14/**
15  *
16  * @param name [[String]] name of fuConfig
17  * @param fuType [[Int]] type of func, select from [[xiangshan.backend.fu.FuType]]
18  * @param fuGen how to create $fu
19  * @param srcData type of src data used by this $fu
20  * @param piped if the $fu is pipelined
21  * @param maybeBlock the $fu need ready signal to block internal pipeline
22  * @param writeIntRf the $fu write int regfiles
23  * @param writeFpRf the $fu write float regfiles
24  * @param writeVecRf the $fu write vector regfiles
25  * @param writeV0Rf the $fu write v0 regfiles
26  * @param writeVlRf the $fu write vl regfiles
27  * @param writeFflags the $fu write fflags csr
28  * @param writeVxsat the $fu write vxsat csr
29  * @param destDataBits the width of output data in the $fu
30  * @param srcDataBits the width of input data in the $fu, the default value is destDataBits
31  * @param latency the latency of instuction executed in the $fu
32  * @param hasInputBuffer if the $fu has input buffer
33  * @param exceptionOut the $fu can produce these exception
34  * @param hasLoadError if the $fu has load error out
35  * @param flushPipe if the instuction executed in the $fu need flush out
36  * @param replayInst if the instuction executed in the $fu can replay in some condition
37  * @param trigger if the $fu need trigger out
38  * @param needSrcFrm if the $fu need float rounding mode signal
39  * @param needSrcVxrm if the $fu need vector fixed-point rounding mode signal
40  * @param immType the immediate type of this $fu
41  * @param vconfigWakeUp
42  * @param maskWakeUp
43  *
44  * @define fu function unit
45  */
46case class FuConfig (
47  name          : String,
48  fuType        : FuType.OHType,
49  fuGen         : (Parameters, FuConfig) => FuncUnit,
50  srcData       : Seq[Seq[DataConfig]],
51  piped         : Boolean,
52  maybeBlock    : Boolean = false,
53  writeIntRf    : Boolean = false,
54  writeFpRf     : Boolean = false,
55  writeVecRf    : Boolean = false,
56  writeV0Rf     : Boolean = false,
57  writeVlRf     : Boolean = false,
58  writeFakeIntRf: Boolean = false,
59  writeFflags   : Boolean = false,
60  writeVxsat    : Boolean = false,
61  destDataBits  : Int = 64,
62  srcDataBits   : Option[Int] = None,
63  latency       : HasFuLatency = CertainLatency(0),// two field (base latency, extra latency(option))
64  hasInputBuffer: (Boolean, Int, Boolean) = (false, 0, false),
65  exceptionOut  : Seq[Int] = Seq(),
66  hasLoadError  : Boolean = false,
67  flushPipe     : Boolean = false,
68  replayInst    : Boolean = false,
69  trigger       : Boolean = false,
70  needSrcFrm    : Boolean = false,
71  needSrcVxrm   : Boolean = false,
72  writeVType    : Boolean = false,
73  immType       : Set[UInt] = Set(),
74  // vector
75  vconfigWakeUp : Boolean = false,
76  maskWakeUp    : Boolean = false,
77) {
78  def needIntWen: Boolean = writeIntRf || writeFakeIntRf
79  def needFpWen:  Boolean = writeFpRf
80  def needVecWen: Boolean = writeVecRf
81  def needV0Wen:  Boolean = writeV0Rf
82  def needVlWen:  Boolean = writeVlRf
83  var vconfigIdx = -1
84  var maskSrcIdx = -1
85  if (vconfigWakeUp) {
86    vconfigIdx = getSpecialSrcIdx(VlData(), "when vconfigWakeUp is true, srcData must always contains VlData()")
87  }
88  if (maskWakeUp) {
89    maskSrcIdx = getSpecialSrcIdx(V0Data(), "when maskWakeUp is true, srcData must always contains V0Data()")
90  }
91
92  require(!piped || piped && latency.latencyVal.isDefined, "The latency value must be set when piped is enable")
93  require(!vconfigWakeUp || vconfigWakeUp && vconfigIdx >= 0, "The index of vl src must be set when vlWakeUp is enable")
94  require(!maskWakeUp || maskWakeUp && maskSrcIdx >= 0, "The index of mask src must be set when vlWakeUp is enable")
95
96  def numIntSrc : Int = srcData.map(_.count(x => IntRegSrcDataSet.contains(x))).fold(0)(_ max _)
97  def numFpSrc  : Int = srcData.map(_.count(x => FpRegSrcDataSet.contains(x))).fold(0)(_ max _)
98  def numVecSrc : Int = srcData.map(_.count(x => VecRegSrcDataSet.contains(x))).fold(0)(_ max _)
99  def numVfSrc  : Int = srcData.map(_.count(x => VecRegSrcDataSet.contains(x))).fold(0)(_ max _)
100  def numV0Src  : Int = srcData.map(_.count(x => V0RegSrcDataSet.contains(x))).fold(0)(_ max _)
101  def numVlSrc  : Int = srcData.map(_.count(x => VlRegSrcDataSet.contains(x))).fold(0)(_ max _)
102  def numRegSrc : Int = srcData.map(_.count(x => RegSrcDataSet.contains(x))).fold(0)(_ max _)
103  def numSrc    : Int = srcData.map(_.length).fold(0)(_ max _)
104
105  def readFp: Boolean = numFpSrc > 0
106
107  def fuSel(uop: ExuInput): Bool = {
108    // Don't add more shit here!!!
109    // Todo: add new FuType to distinguish f2i, f2f
110    uop.fuType === this.fuType.U
111  }
112
113  /**
114    * params(i): data type set of the ith src port
115    * @return
116    */
117  def getRfReadDataCfgSet: Seq[Set[DataConfig]] = {
118    val numSrcMax = srcData.map(_.length).fold(0)(_ max _)
119    // make srcData is uniform sized to avoid exception when transpose
120    val alignedSrcData: Seq[Seq[DataConfig]] = srcData.map(x => x ++ Seq.fill(numSrcMax - x.length)(null))
121    alignedSrcData.transpose.map(_.toSet.intersect(RegSrcDataSet))
122  }
123
124  def getSrcDataType(srcIdx: Int): Set[DataConfig] = {
125    srcData
126      .map((x: Seq[DataConfig]) => if(x.isDefinedAt(srcIdx)) Some(x(srcIdx)) else None)
127      .filter(_.nonEmpty)
128      .map(_.get)
129      .toSet
130  }
131
132  def hasNoDataWB: Boolean = {
133    !(writeIntRf || writeFpRf || writeVecRf || writeV0Rf || writeVlRf)
134  }
135
136  def getSrcMaxWidthVec = {
137    getRfReadDataCfgSet.map(_.map(_.dataWidth).max)
138  }
139
140  def genSrcDataVec: Seq[UInt] = {
141    getSrcMaxWidthVec.map(w => UInt(w.W))
142  }
143
144  // csr's redirect also uses redirect bundle
145  def hasRedirect: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr).contains(fuType)
146
147  def hasPredecode: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr, FuType.ldu).contains(fuType)
148
149  def needTargetPc: Boolean = Seq(FuType.jmp, FuType.brh).contains(fuType)
150
151  // predict info
152  def needPdInfo: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr).contains(fuType)
153
154  def needPc: Boolean = Seq(FuType.jmp, FuType.brh, FuType.ldu).contains(fuType)
155
156  def needFPUCtrl: Boolean = {
157    import FuType._
158    Seq(fmac, fDivSqrt, i2f).contains(fuType)
159  }
160
161  def needVecCtrl: Boolean = {
162    import FuType._
163    Seq(vipu, vialuF, vimac, vidiv, vfpu, vppu, vfalu, vfma, vfdiv, vfcvt, vldu, vstu).contains(fuType)
164  }
165
166  def needCriticalErrors: Boolean = Seq(FuType.csr).contains(fuType)
167
168  def isMul: Boolean = fuType == FuType.mul
169
170  def isDiv: Boolean = fuType == FuType.div
171
172  def isCsr: Boolean = fuType == FuType.csr
173
174  def isBrh: Boolean = fuType == FuType.brh
175
176  def isJmp: Boolean = fuType == FuType.jmp
177
178  def isFence: Boolean = fuType == FuType.fence
179
180  def isVecArith: Boolean = fuType == FuType.vialuF || fuType == FuType.vimac ||
181                            fuType == FuType.vppu || fuType == FuType.vipu ||
182                            fuType == FuType.vfalu || fuType == FuType.vfma ||
183                            fuType == FuType.vfdiv || fuType == FuType.vfcvt ||
184                            fuType == FuType.vidiv
185
186  def isVecMem: Boolean = fuType == FuType.vldu || fuType == FuType.vstu ||
187                          fuType == FuType.vsegldu || fuType == FuType.vsegstu
188
189  def needOg2: Boolean = isVecArith || fuType == FuType.vsetfwf || isVecMem
190
191  def isSta: Boolean = name.contains("sta")
192
193  def isStd: Boolean = name.contains("std")
194
195  def ckAlwaysEn: Boolean = isCsr || isFence
196
197  /**
198    * Get index of special src data, like [[VlData]], [[V0Data]]
199   *
200    * @param data [[DataConfig]]
201    * @param tips tips if get failed
202    * @return the index of special src data
203    */
204  protected def getSpecialSrcIdx(data: DataConfig, tips: String): Int = {
205    val srcIdxVec = srcData.map(x => x.indexOf(data))
206    val idx0 = srcIdxVec.head
207    for (idx <- srcIdxVec) {
208      require(idx >= 0 && idx == idx0, tips + ", and at the same index.")
209    }
210    idx0
211  }
212
213  override def toString: String = {
214    var str = s"${this.name}: "
215    if (vconfigWakeUp) str += s"vconfigIdx($vconfigIdx), "
216    if (maskWakeUp) str += s"maskSrcIdx($maskSrcIdx), "
217    str += s"latency($latency)"
218    str += s"src($srcData)"
219    str
220  }
221}
222
223object FuConfig {
224  val JmpCfg: FuConfig = FuConfig (
225    name = "jmp",
226    fuType = FuType.jmp,
227    fuGen = (p: Parameters, cfg: FuConfig) => Module(new JumpUnit(cfg)(p)).suggestName("jmp"),
228    srcData = Seq(
229      Seq(IntData()), // jal
230    ),
231    piped = true,
232    writeIntRf = true,
233    immType = Set(SelImm.IMM_I, SelImm.IMM_UJ, SelImm.IMM_U),
234  )
235
236  val BrhCfg: FuConfig = FuConfig (
237    name = "brh",
238    fuType = FuType.brh,
239    fuGen = (p: Parameters, cfg: FuConfig) => Module(new BranchUnit(cfg)(p).suggestName("brh")),
240    srcData = Seq(
241      Seq(IntData(), IntData()),
242    ),
243    piped = true,
244    immType = Set(SelImm.IMM_SB),
245  )
246
247  val I2fCfg: FuConfig = FuConfig (
248    name = "i2f",
249    FuType.i2f,
250    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntToFP(cfg)(p).suggestName("i2f")),
251    srcData = Seq(
252      Seq(IntData()),
253    ),
254    piped = true,
255    writeFpRf = true,
256    writeFflags = true,
257    latency = CertainLatency(2),
258    needSrcFrm = true,
259  )
260
261  val I2vCfg: FuConfig = FuConfig (
262    name = "i2v",
263    FuType.i2v,
264    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntFPToVec(cfg)(p).suggestName("i2v")),
265    srcData = Seq(
266      Seq(IntData(), IntData()),
267    ),
268    piped = true,
269    writeFpRf = true,
270    writeVecRf = true,
271    writeV0Rf = true,
272    latency = CertainLatency(0),
273    destDataBits = 128,
274    srcDataBits = Some(64),
275    immType = Set(SelImm.IMM_OPIVIU, SelImm.IMM_OPIVIS, SelImm.IMM_VRORVI),
276  )
277
278  val F2vCfg: FuConfig = FuConfig (
279    name = "f2v",
280    FuType.f2v,
281    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntFPToVec(cfg)(p).suggestName("f2v")),
282    srcData = Seq(
283      Seq(FpData(), FpData()),
284      Seq(FpData()),
285    ),
286    piped = true,
287    writeFpRf = true,
288    writeVecRf = true,
289    writeV0Rf = true,
290    latency = CertainLatency(0),
291    destDataBits = 128,
292    srcDataBits = Some(64),
293  )
294
295  val CsrCfg: FuConfig = FuConfig (
296    name = "csr",
297    fuType = FuType.csr,
298    fuGen = (p: Parameters, cfg: FuConfig) => Module(new CSR(cfg)(p).suggestName("csr")),
299    srcData = Seq(
300      Seq(IntData()),
301    ),
302    piped = false,
303    writeIntRf = true,
304    latency = UncertainLatency(),
305    exceptionOut = Seq(illegalInstr, virtualInstr, breakPoint, ecallU, ecallS, ecallVS, ecallM),
306    flushPipe = true,
307  )
308
309  val AluCfg: FuConfig = FuConfig (
310    name = "alu",
311    fuType = FuType.alu,
312    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Alu(cfg)(p).suggestName("Alu")),
313    srcData = Seq(
314      Seq(IntData(), IntData()),
315    ),
316    piped = true,
317    writeIntRf = true,
318    immType = Set(SelImm.IMM_I, SelImm.IMM_U, SelImm.IMM_LUI32),
319  )
320
321  val MulCfg: FuConfig = FuConfig (
322    name = "mul",
323    fuType = FuType.mul,
324    fuGen = (p: Parameters, cfg: FuConfig) => Module(new MulUnit(cfg)(p).suggestName("Mul")),
325    srcData = Seq(
326      Seq(IntData(), IntData()),
327    ),
328    piped = true,
329    writeIntRf = true,
330    latency = CertainLatency(2),
331  )
332
333  val DivCfg: FuConfig = FuConfig (
334    name = "div",
335    fuType = FuType.div,
336    fuGen = (p: Parameters, cfg: FuConfig) => Module(new DivUnit(cfg)(p).suggestName("Div")),
337    srcData = Seq(
338      Seq(IntData(), IntData()),
339    ),
340    piped = false,
341    writeIntRf = true,
342    latency = UncertainLatency(),
343    hasInputBuffer = (true, 4, true)
344  )
345
346  val FenceCfg: FuConfig = FuConfig (
347    name = "fence",
348    FuType.fence,
349    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Fence(cfg)(p).suggestName("Fence")),
350    srcData = Seq(
351      Seq(IntData(), IntData()),
352    ),
353    piped = false,
354    latency = UncertainLatency(),
355    exceptionOut = Seq(illegalInstr, virtualInstr),
356    flushPipe = true
357  )
358
359  // Todo: split it to simple bitmap exu and complex bku
360  val BkuCfg: FuConfig = FuConfig (
361    name = "bku",
362    fuType = FuType.bku,
363    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Bku(cfg)(p).suggestName("Bku")),
364    srcData = Seq(
365      Seq(IntData(), IntData()),
366    ),
367    piped = true,
368    writeIntRf = true,
369    latency = CertainLatency(2),
370  )
371
372  val VSetRvfWvfCfg: FuConfig = FuConfig(
373    name = "vsetrvfwvf",
374    fuType = FuType.vsetfwf,
375    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRvfWvf(cfg)(p).suggestName("VSetRvfWvf")),
376    srcData = Seq(
377      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
378    ),
379    piped = true,
380    writeVlRf = true,
381    writeVType = true,
382    writeIntRf = true,
383    latency = CertainLatency(0),
384    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
385  )
386
387  val VSetRiWvfCfg: FuConfig = FuConfig(
388    name = "vsetriwvf",
389    fuType = FuType.vsetiwf,
390    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWvf(cfg)(p).suggestName("VSetRiWvf")),
391    srcData = Seq(
392      Seq(IntData(), IntData()),
393    ),
394    piped = true,
395    writeVlRf = true,
396    writeVType = true,
397    latency = CertainLatency(0),
398    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
399  )
400
401  val VSetRiWiCfg: FuConfig = FuConfig(
402    name = "vsetriwi",
403    fuType = FuType.vsetiwi,
404    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWi(cfg)(p).suggestName("VSetRiWi")),
405    srcData = Seq(
406      Seq(IntData(), IntData()),
407    ),
408    piped = true,
409    writeIntRf = true,
410    latency = CertainLatency(0),
411    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
412  )
413
414  val LduCfg: FuConfig = FuConfig (
415    name = "ldu",
416    fuType = FuType.ldu,
417    fuGen = null, // Todo
418    srcData = Seq(
419      Seq(IntData()),
420    ),
421    piped = false, // Todo: check it
422    writeIntRf = true,
423    writeFpRf = true,
424    latency = UncertainLatency(3),
425    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault, breakPoint, hardwareError),
426    flushPipe = true,
427    replayInst = true,
428    hasLoadError = true,
429    trigger = true,
430    immType = Set(SelImm.IMM_I),
431  )
432
433  val StaCfg: FuConfig = FuConfig (
434    name = "sta",
435    fuType = FuType.stu,
436    fuGen = null, // Todo
437    srcData = Seq(
438      Seq(IntData()),
439    ),
440    piped = false,
441    latency = UncertainLatency(),
442    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault, breakPoint),
443    flushPipe = true,
444    trigger = true,
445    immType = Set(SelImm.IMM_S),
446  )
447
448  val StdCfg: FuConfig = FuConfig (
449    name = "std",
450    fuType = FuType.stu,
451    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")),
452    srcData = Seq(
453      Seq(IntData()),
454      Seq(FpData()),
455    ),
456    piped = true,
457    latency = CertainLatency(0)
458  )
459
460  val HyldaCfg = FuConfig (
461    name = "hylda",
462    fuType = FuType.ldu,
463    fuGen = null, // Todo
464    srcData = Seq(
465      Seq(IntData()),
466    ),
467    piped = false, // Todo: check it
468    writeIntRf = true,
469    writeFpRf = true,
470    latency = UncertainLatency(3),
471    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault),
472    flushPipe = true,
473    replayInst = true,
474    hasLoadError = true,
475    immType = Set(SelImm.IMM_I),
476  )
477
478  val HystaCfg = FuConfig (
479    name = "hysta",
480    fuType = FuType.stu,
481    fuGen = null, // Todo
482    srcData = Seq(
483      Seq(IntData()),
484    ),
485    piped = false,
486    latency = UncertainLatency(),
487    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault),
488    immType = Set(SelImm.IMM_S),
489  )
490
491  val FakeHystaCfg = FuConfig (
492    name = "hysta",
493    fuType = FuType.stu,
494    fuGen = null, // Todo
495    srcData = Seq(),
496    piped = false,
497    latency = UncertainLatency(),
498    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault),
499    immType = Set(),
500  )
501
502  val MouCfg: FuConfig = FuConfig (
503    name = "mou",
504    fuType = FuType.mou,
505    fuGen = null, // Todo
506    srcData = Seq(
507      Seq(IntData()),
508    ),
509    piped = false, // Todo: check it
510    writeFakeIntRf = true,
511    latency = UncertainLatency(),
512    exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct,
513    trigger = true,
514  )
515
516  val MoudCfg: FuConfig = FuConfig (
517    name = "moud",
518    fuType = FuType.mou,
519    fuGen = null, // Todo
520    srcData = Seq(
521      Seq(IntData()),
522    ),
523    piped = true,
524    latency = CertainLatency(0),
525  )
526
527  val VialuCfg = FuConfig (
528    name = "vialuFix",
529    fuType = FuType.vialuF,
530    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIAluFix(cfg)(p).suggestName("VialuFix")),
531    srcData = Seq(
532      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
533    ),
534    piped = true,
535    writeVecRf = true,
536    writeV0Rf = true,
537    writeVxsat = true,
538    needSrcVxrm = true,
539    latency = CertainLatency(1),
540    vconfigWakeUp = true,
541    maskWakeUp = true,
542    destDataBits = 128,
543    exceptionOut = Seq(illegalInstr),
544  )
545
546  val VimacCfg = FuConfig (
547    name = "vimac",
548    fuType = FuType.vimac,
549    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIMacU(cfg)(p).suggestName("Vimac")),
550    srcData = Seq(
551      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
552    ),
553    piped = true,
554    writeVecRf = true,
555    writeV0Rf = true,
556    writeVxsat = true,
557    needSrcVxrm = true,
558    latency = CertainLatency(2),
559    vconfigWakeUp = true,
560    maskWakeUp = true,
561    destDataBits = 128,
562    exceptionOut = Seq(illegalInstr),
563  )
564
565  val VidivCfg = FuConfig (
566    name = "vidiv",
567    fuType = FuType.vidiv,
568    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIDiv(cfg)(p).suggestName("Vidiv")),
569    srcData = Seq(
570      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
571    ),
572    piped = false,
573    writeVecRf = true,
574    writeV0Rf = true,
575    latency = UncertainLatency(),
576    vconfigWakeUp = true,
577    maskWakeUp = true,
578    destDataBits = 128,
579    exceptionOut = Seq(illegalInstr),
580  )
581
582  val VppuCfg = FuConfig (
583    name = "vppu",
584    fuType = FuType.vppu,
585    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VPPU(cfg)(p).suggestName("Vppu")),
586    srcData = Seq(
587      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
588    ),
589    piped = true,
590    writeVecRf = true,
591    writeV0Rf = true,
592    latency = CertainLatency(2),
593    vconfigWakeUp = true,
594    maskWakeUp = true,
595    destDataBits = 128,
596    exceptionOut = Seq(illegalInstr),
597  )
598
599  val VipuCfg: FuConfig = FuConfig (
600    name = "vipu",
601    fuType = FuType.vipu,
602    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIPU(cfg)(p).suggestName("Vipu")),
603    srcData = Seq(
604      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0
605    ),
606    piped = true,
607    writeIntRf = true,
608    writeVecRf = true,
609    writeV0Rf = true,
610    latency = CertainLatency(2),
611    vconfigWakeUp = true,
612    maskWakeUp = true,
613    destDataBits = 128,
614    exceptionOut = Seq(illegalInstr),
615  )
616
617  val VfaluCfg = FuConfig (
618    name = "vfalu",
619    fuType = FuType.vfalu,
620    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFAlu(cfg)(p).suggestName("Vfalu")),
621    srcData = Seq(
622      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
623    ),
624    piped = true,
625    writeVecRf = true,
626    writeV0Rf = true,
627    writeFpRf = true,
628    writeFflags = true,
629    latency = CertainLatency(1),
630    vconfigWakeUp = true,
631    maskWakeUp = true,
632    destDataBits = 128,
633    exceptionOut = Seq(illegalInstr),
634    needSrcFrm = true,
635  )
636
637  val VfmaCfg = FuConfig (
638    name = "vfma",
639    fuType = FuType.vfma,
640    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFMA(cfg)(p).suggestName("Vfma")),
641    srcData = Seq(
642      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
643    ),
644    piped = true,
645    writeVecRf = true,
646    writeV0Rf = true,
647    writeFflags = true,
648    latency = CertainLatency(3),
649    vconfigWakeUp = true,
650    maskWakeUp = true,
651    destDataBits = 128,
652    exceptionOut = Seq(illegalInstr),
653    needSrcFrm = true,
654  )
655
656  val VfdivCfg = FuConfig(
657    name = "vfdiv",
658    fuType = FuType.vfdiv,
659    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFDivSqrt(cfg)(p).suggestName("Vfdiv")),
660    srcData = Seq(
661      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
662    ),
663    piped = false,
664    writeVecRf = true,
665    writeV0Rf = true,
666    writeFflags = true,
667    latency = UncertainLatency(),
668    vconfigWakeUp = true,
669    maskWakeUp = true,
670    destDataBits = 128,
671    exceptionOut = Seq(illegalInstr),
672    needSrcFrm = true,
673  )
674
675  val VfcvtCfg = FuConfig(
676    name = "vfcvt",
677    fuType = FuType.vfcvt,
678    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VCVT(cfg)(p).suggestName("Vfcvt")),
679    srcData = Seq(
680      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
681    ),
682    piped = true,
683    writeVecRf = true,
684    writeV0Rf = true,
685    writeFflags = true,
686    latency = CertainLatency(2),
687    vconfigWakeUp = true,
688    maskWakeUp = true,
689    destDataBits = 128,
690    exceptionOut = Seq(illegalInstr),
691    needSrcFrm = true,
692  )
693
694  val FaluCfg = FuConfig(
695    name = "falu",
696    fuType = FuType.falu,
697    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FAlu(cfg)(p).suggestName("Falu")),
698    srcData = Seq(
699      Seq(FpData(), FpData()),
700    ),
701    piped = true,
702    writeFpRf = true,
703    writeIntRf = true,
704    writeFflags = true,
705    latency = CertainLatency(1),
706    destDataBits = 64,
707    needSrcFrm = true,
708  )
709
710  val FmacCfg = FuConfig(
711    name = "fmac",
712    fuType = FuType.fmac,
713    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("Fmac")),
714    srcData = Seq(
715      Seq(FpData(), FpData(), FpData()),
716    ),
717    piped = true,
718    writeFpRf = true,
719    writeFflags = true,
720    latency = CertainLatency(3),
721    destDataBits = 64,
722    needSrcFrm = true,
723  )
724
725  val FdivCfg = FuConfig(
726    name = "fdiv",
727    fuType = FuType.fDivSqrt,
728    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("Fdiv")),
729    srcData = Seq(
730      Seq(FpData(), FpData()),
731    ),
732    piped = false,
733    writeFpRf = true,
734    writeFflags = true,
735    latency = UncertainLatency(),
736    destDataBits = 64,
737    needSrcFrm = true,
738  )
739
740  val FcvtCfg = FuConfig(
741    name = "fcvt",
742    fuType = FuType.fcvt,
743    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FCVT(cfg)(p).suggestName("Fcvt")),
744    srcData = Seq(
745      Seq(FpData()),
746    ),
747    piped = true,
748    writeFpRf = true,
749    writeIntRf = true,
750    writeFflags = true,
751    latency = CertainLatency(2),
752    destDataBits = 64,
753    needSrcFrm = true,
754  )
755
756  val VlduCfg: FuConfig = FuConfig (
757    name = "vldu",
758    fuType = FuType.vldu,
759    fuGen = null,
760    srcData = Seq(
761      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  //vs1, vs2, vd_old, v0, vconfig
762    ),
763    piped = false, // Todo: check it
764    writeVecRf = true,
765    writeV0Rf = true,
766    writeVlRf = true,
767    latency = UncertainLatency(),
768    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault, breakPoint),
769    flushPipe = true,
770    replayInst = true,
771    trigger = true,
772    hasLoadError = true,
773    vconfigWakeUp = true,
774    maskWakeUp = true,
775    destDataBits = 128,
776  )
777
778  val VstuCfg: FuConfig = FuConfig (
779    name = "vstu",
780    fuType = FuType.vstu,
781    fuGen = null,
782    srcData = Seq(
783      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  //vs1, vs2, vd_old, v0, vconfig
784    ),
785    piped = false,
786    latency = UncertainLatency(),
787    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault, breakPoint),
788    flushPipe = true,
789    replayInst = true,
790    trigger = true,
791    hasLoadError = true,
792    vconfigWakeUp = true,
793    maskWakeUp = true,
794    destDataBits = 128,
795  )
796
797  val VseglduSeg: FuConfig = FuConfig (
798    name = "vsegldu",
799    fuType = FuType.vsegldu,
800    fuGen = null,
801    srcData = Seq(
802      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), //vs1, vs2, vd_old, v0, vconfig
803    ),
804    piped = false, // Todo: check it
805    writeVecRf = true,
806    writeV0Rf = true,
807    writeVlRf = true,
808    latency = UncertainLatency(),
809    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, breakPoint),
810    flushPipe = true,
811    replayInst = true,
812    trigger = true,
813    hasLoadError = true,
814    vconfigWakeUp = true,
815    maskWakeUp = true,
816    destDataBits = 128,
817  )
818
819  val VsegstuCfg: FuConfig = FuConfig(
820    name = "vsegstu",
821    fuType = FuType.vsegstu,
822    fuGen = null,
823    srcData = Seq(
824      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), //vs1, vs2, vd_old, v0, vconfig
825    ),
826    piped = false,
827    latency = UncertainLatency(),
828    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, breakPoint),
829    flushPipe = true,
830    replayInst = true,
831    trigger = true,
832    hasLoadError = true,
833    vconfigWakeUp = true,
834    maskWakeUp = true,
835    destDataBits = 128,
836  )
837
838  def allConfigs = Seq(
839    JmpCfg, BrhCfg, I2fCfg, I2vCfg, F2vCfg, CsrCfg, AluCfg, MulCfg, DivCfg, FenceCfg, BkuCfg, VSetRvfWvfCfg, VSetRiWvfCfg, VSetRiWiCfg,
840    LduCfg, StaCfg, StdCfg, MouCfg, MoudCfg, VialuCfg, VipuCfg, VlduCfg, VstuCfg, VseglduSeg, VsegstuCfg,
841    FaluCfg, FmacCfg, FcvtCfg, FdivCfg,
842    VfaluCfg, VfmaCfg, VfcvtCfg, HyldaCfg, HystaCfg
843  )
844
845  def VecArithFuConfigs = Seq(
846    VialuCfg, VimacCfg, VppuCfg, VipuCfg, VfaluCfg, VfmaCfg, VfcvtCfg
847  )
848}
849
850