xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FuConfig.scala (revision 211d620b07edb797ba35b635d24fef4e7294bae2)
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, FuType.csr).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.fence).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(falu, fmac, fDivSqrt, fcvt,
164      vipu, vialuF, vimac, vidiv, vfpu, vppu, vfalu, vfma, vfdiv, vfcvt, vldu, vstu).contains(fuType)
165  }
166
167  def needCriticalErrors: Boolean = Seq(FuType.csr).contains(fuType)
168
169  def isMul: Boolean = fuType == FuType.mul
170
171  def isDiv: Boolean = fuType == FuType.div
172
173  def isCsr: Boolean = fuType == FuType.csr
174
175  def isBrh: Boolean = fuType == FuType.brh
176
177  def isJmp: Boolean = fuType == FuType.jmp
178
179  def isFence: Boolean = fuType == FuType.fence
180
181  def isVecArith: Boolean = fuType == FuType.vialuF || fuType == FuType.vimac ||
182                            fuType == FuType.vppu || fuType == FuType.vipu ||
183                            fuType == FuType.vfalu || fuType == FuType.vfma ||
184                            fuType == FuType.vfdiv || fuType == FuType.vfcvt ||
185                            fuType == FuType.vidiv
186
187  def isVecMem: Boolean = fuType == FuType.vldu || fuType == FuType.vstu ||
188                          fuType == FuType.vsegldu || fuType == FuType.vsegstu
189
190  def needOg2: Boolean = isVecArith || fuType == FuType.vsetfwf || isVecMem
191
192  def isSta: Boolean = name.contains("sta")
193
194  def ckAlwaysEn: Boolean = isCsr || isFence
195
196  /**
197    * Get index of special src data, like [[VlData]], [[V0Data]]
198   *
199    * @param data [[DataConfig]]
200    * @param tips tips if get failed
201    * @return the index of special src data
202    */
203  protected def getSpecialSrcIdx(data: DataConfig, tips: String): Int = {
204    val srcIdxVec = srcData.map(x => x.indexOf(data))
205    val idx0 = srcIdxVec.head
206    for (idx <- srcIdxVec) {
207      require(idx >= 0 && idx == idx0, tips + ", and at the same index.")
208    }
209    idx0
210  }
211
212  override def toString: String = {
213    var str = s"${this.name}: "
214    if (vconfigWakeUp) str += s"vconfigIdx($vconfigIdx), "
215    if (maskWakeUp) str += s"maskSrcIdx($maskSrcIdx), "
216    str += s"latency($latency)"
217    str += s"src($srcData)"
218    str
219  }
220}
221
222object FuConfig {
223  val JmpCfg: FuConfig = FuConfig (
224    name = "jmp",
225    fuType = FuType.jmp,
226    fuGen = (p: Parameters, cfg: FuConfig) => Module(new JumpUnit(cfg)(p)).suggestName("jmp"),
227    srcData = Seq(
228      Seq(IntData()), // jal
229    ),
230    piped = true,
231    writeIntRf = true,
232    immType = Set(SelImm.IMM_I, SelImm.IMM_UJ, SelImm.IMM_U),
233  )
234
235  val BrhCfg: FuConfig = FuConfig (
236    name = "brh",
237    fuType = FuType.brh,
238    fuGen = (p: Parameters, cfg: FuConfig) => Module(new BranchUnit(cfg)(p).suggestName("brh")),
239    srcData = Seq(
240      Seq(IntData(), IntData()),
241    ),
242    piped = true,
243    immType = Set(SelImm.IMM_SB),
244  )
245
246  val I2fCfg: FuConfig = FuConfig (
247    name = "i2f",
248    FuType.i2f,
249    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntToFP(cfg)(p).suggestName("i2f")),
250    srcData = Seq(
251      Seq(IntData()),
252    ),
253    piped = true,
254    writeFpRf = true,
255    writeFflags = true,
256    latency = CertainLatency(2),
257    needSrcFrm = true,
258  )
259
260  val I2vCfg: FuConfig = FuConfig (
261    name = "i2v",
262    FuType.i2v,
263    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntFPToVec(cfg)(p).suggestName("i2v")),
264    srcData = Seq(
265      Seq(IntData(), IntData()),
266    ),
267    piped = true,
268    writeFpRf = true,
269    writeVecRf = true,
270    writeV0Rf = true,
271    latency = CertainLatency(0),
272    destDataBits = 128,
273    srcDataBits = Some(64),
274    immType = Set(SelImm.IMM_OPIVIU, SelImm.IMM_OPIVIS, SelImm.IMM_VRORVI),
275  )
276
277  val F2vCfg: FuConfig = FuConfig (
278    name = "f2v",
279    FuType.f2v,
280    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntFPToVec(cfg)(p).suggestName("f2v")),
281    srcData = Seq(
282      Seq(FpData(), FpData()),
283      Seq(FpData()),
284    ),
285    piped = true,
286    writeFpRf = true,
287    writeVecRf = true,
288    writeV0Rf = true,
289    latency = CertainLatency(0),
290    destDataBits = 128,
291    srcDataBits = Some(64),
292  )
293
294  val CsrCfg: FuConfig = FuConfig (
295    name = "csr",
296    fuType = FuType.csr,
297    fuGen = (p: Parameters, cfg: FuConfig) => Module(new CSR(cfg)(p).suggestName("csr")),
298    srcData = Seq(
299      Seq(IntData()),
300    ),
301    piped = false,
302    writeIntRf = true,
303    latency = UncertainLatency(),
304    exceptionOut = Seq(illegalInstr, virtualInstr, breakPoint, ecallU, ecallS, ecallVS, ecallM),
305    flushPipe = true,
306  )
307
308  val AluCfg: FuConfig = FuConfig (
309    name = "alu",
310    fuType = FuType.alu,
311    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Alu(cfg)(p).suggestName("Alu")),
312    srcData = Seq(
313      Seq(IntData(), IntData()),
314    ),
315    piped = true,
316    writeIntRf = true,
317    immType = Set(SelImm.IMM_I, SelImm.IMM_U, SelImm.IMM_LUI32),
318  )
319
320  val MulCfg: FuConfig = FuConfig (
321    name = "mul",
322    fuType = FuType.mul,
323    fuGen = (p: Parameters, cfg: FuConfig) => Module(new MulUnit(cfg)(p).suggestName("Mul")),
324    srcData = Seq(
325      Seq(IntData(), IntData()),
326    ),
327    piped = true,
328    writeIntRf = true,
329    latency = CertainLatency(2),
330  )
331
332  val DivCfg: FuConfig = FuConfig (
333    name = "div",
334    fuType = FuType.div,
335    fuGen = (p: Parameters, cfg: FuConfig) => Module(new DivUnit(cfg)(p).suggestName("Div")),
336    srcData = Seq(
337      Seq(IntData(), IntData()),
338    ),
339    piped = false,
340    writeIntRf = true,
341    latency = UncertainLatency(),
342    hasInputBuffer = (true, 4, true)
343  )
344
345  val FenceCfg: FuConfig = FuConfig (
346    name = "fence",
347    FuType.fence,
348    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Fence(cfg)(p).suggestName("Fence")),
349    srcData = Seq(
350      Seq(IntData(), IntData()),
351    ),
352    piped = false,
353    latency = UncertainLatency(),
354    exceptionOut = Seq(illegalInstr, virtualInstr),
355    flushPipe = true
356  )
357
358  // Todo: split it to simple bitmap exu and complex bku
359  val BkuCfg: FuConfig = FuConfig (
360    name = "bku",
361    fuType = FuType.bku,
362    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Bku(cfg)(p).suggestName("Bku")),
363    srcData = Seq(
364      Seq(IntData(), IntData()),
365    ),
366    piped = true,
367    writeIntRf = true,
368    latency = CertainLatency(2),
369  )
370
371  val VSetRvfWvfCfg: FuConfig = FuConfig(
372    name = "vsetrvfwvf",
373    fuType = FuType.vsetfwf,
374    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRvfWvf(cfg)(p).suggestName("VSetRvfWvf")),
375    srcData = Seq(
376      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
377    ),
378    piped = true,
379    writeVlRf = true,
380    writeVType = true,
381    writeIntRf = true,
382    latency = CertainLatency(0),
383    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
384  )
385
386  val VSetRiWvfCfg: FuConfig = FuConfig(
387    name = "vsetriwvf",
388    fuType = FuType.vsetiwf,
389    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWvf(cfg)(p).suggestName("VSetRiWvf")),
390    srcData = Seq(
391      Seq(IntData(), IntData()),
392    ),
393    piped = true,
394    writeVlRf = true,
395    writeVType = true,
396    latency = CertainLatency(0),
397    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
398  )
399
400  val VSetRiWiCfg: FuConfig = FuConfig(
401    name = "vsetriwi",
402    fuType = FuType.vsetiwi,
403    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWi(cfg)(p).suggestName("VSetRiWi")),
404    srcData = Seq(
405      Seq(IntData(), IntData()),
406    ),
407    piped = true,
408    writeIntRf = true,
409    latency = CertainLatency(0),
410    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
411  )
412
413  val LduCfg: FuConfig = FuConfig (
414    name = "ldu",
415    fuType = FuType.ldu,
416    fuGen = null, // Todo
417    srcData = Seq(
418      Seq(IntData()),
419    ),
420    piped = false, // Todo: check it
421    writeIntRf = true,
422    writeFpRf = true,
423    latency = UncertainLatency(3),
424    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault, breakPoint),
425    flushPipe = true,
426    replayInst = true,
427    hasLoadError = true,
428    trigger = true,
429    immType = Set(SelImm.IMM_I),
430  )
431
432  val StaCfg: FuConfig = FuConfig (
433    name = "sta",
434    fuType = FuType.stu,
435    fuGen = null, // Todo
436    srcData = Seq(
437      Seq(IntData()),
438    ),
439    piped = false,
440    latency = UncertainLatency(),
441    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault, breakPoint),
442    flushPipe = true,
443    trigger = true,
444    immType = Set(SelImm.IMM_S),
445  )
446
447  val StdCfg: FuConfig = FuConfig (
448    name = "std",
449    fuType = FuType.stu,
450    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")),
451    srcData = Seq(
452      Seq(IntData()),
453      Seq(FpData()),
454    ),
455    piped = true,
456    latency = CertainLatency(0)
457  )
458
459  val HyldaCfg = FuConfig (
460    name = "hylda",
461    fuType = FuType.ldu,
462    fuGen = null, // Todo
463    srcData = Seq(
464      Seq(IntData()),
465    ),
466    piped = false, // Todo: check it
467    writeIntRf = true,
468    writeFpRf = true,
469    latency = UncertainLatency(3),
470    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault),
471    flushPipe = true,
472    replayInst = true,
473    hasLoadError = true,
474    immType = Set(SelImm.IMM_I),
475  )
476
477  val HystaCfg = FuConfig (
478    name = "hysta",
479    fuType = FuType.stu,
480    fuGen = null, // Todo
481    srcData = Seq(
482      Seq(IntData()),
483    ),
484    piped = false,
485    latency = UncertainLatency(),
486    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault),
487    immType = Set(SelImm.IMM_S),
488  )
489
490  val FakeHystaCfg = FuConfig (
491    name = "hysta",
492    fuType = FuType.stu,
493    fuGen = null, // Todo
494    srcData = Seq(),
495    piped = false,
496    latency = UncertainLatency(),
497    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault),
498    immType = Set(),
499  )
500
501  val MouCfg: FuConfig = FuConfig (
502    name = "mou",
503    fuType = FuType.mou,
504    fuGen = null, // Todo
505    srcData = Seq(
506      Seq(IntData()),
507    ),
508    piped = false, // Todo: check it
509    writeFakeIntRf = true,
510    latency = UncertainLatency(),
511    exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct,
512    trigger = true,
513  )
514
515  val MoudCfg: FuConfig = FuConfig (
516    name = "moud",
517    fuType = FuType.mou,
518    fuGen = null, // Todo
519    srcData = Seq(
520      Seq(IntData()),
521    ),
522    piped = true,
523    latency = CertainLatency(0),
524  )
525
526  val VialuCfg = FuConfig (
527    name = "vialuFix",
528    fuType = FuType.vialuF,
529    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIAluFix(cfg)(p).suggestName("VialuFix")),
530    srcData = Seq(
531      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
532    ),
533    piped = true,
534    writeVecRf = true,
535    writeV0Rf = true,
536    writeVxsat = true,
537    needSrcVxrm = true,
538    latency = CertainLatency(1),
539    vconfigWakeUp = true,
540    maskWakeUp = true,
541    destDataBits = 128,
542    exceptionOut = Seq(illegalInstr),
543  )
544
545  val VimacCfg = FuConfig (
546    name = "vimac",
547    fuType = FuType.vimac,
548    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIMacU(cfg)(p).suggestName("Vimac")),
549    srcData = Seq(
550      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
551    ),
552    piped = true,
553    writeVecRf = true,
554    writeV0Rf = true,
555    writeVxsat = true,
556    needSrcVxrm = true,
557    latency = CertainLatency(2),
558    vconfigWakeUp = true,
559    maskWakeUp = true,
560    destDataBits = 128,
561    exceptionOut = Seq(illegalInstr),
562  )
563
564  val VidivCfg = FuConfig (
565    name = "vidiv",
566    fuType = FuType.vidiv,
567    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIDiv(cfg)(p).suggestName("Vidiv")),
568    srcData = Seq(
569      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
570    ),
571    piped = false,
572    writeVecRf = true,
573    writeV0Rf = true,
574    latency = UncertainLatency(),
575    vconfigWakeUp = true,
576    maskWakeUp = true,
577    destDataBits = 128,
578    exceptionOut = Seq(illegalInstr),
579  )
580
581  val VppuCfg = FuConfig (
582    name = "vppu",
583    fuType = FuType.vppu,
584    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VPPU(cfg)(p).suggestName("Vppu")),
585    srcData = Seq(
586      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0, vtype&vl
587    ),
588    piped = true,
589    writeVecRf = true,
590    writeV0Rf = true,
591    latency = CertainLatency(2),
592    vconfigWakeUp = true,
593    maskWakeUp = true,
594    destDataBits = 128,
595    exceptionOut = Seq(illegalInstr),
596  )
597
598  val VipuCfg: FuConfig = FuConfig (
599    name = "vipu",
600    fuType = FuType.vipu,
601    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VIPU(cfg)(p).suggestName("Vipu")),
602    srcData = Seq(
603      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  // vs1, vs2, vd_old, v0
604    ),
605    piped = true,
606    writeIntRf = true,
607    writeVecRf = true,
608    writeV0Rf = true,
609    latency = CertainLatency(2),
610    vconfigWakeUp = true,
611    maskWakeUp = true,
612    destDataBits = 128,
613    exceptionOut = Seq(illegalInstr),
614  )
615
616  val VfaluCfg = FuConfig (
617    name = "vfalu",
618    fuType = FuType.vfalu,
619    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFAlu(cfg)(p).suggestName("Vfalu")),
620    srcData = Seq(
621      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
622    ),
623    piped = true,
624    writeVecRf = true,
625    writeV0Rf = true,
626    writeFpRf = true,
627    writeFflags = true,
628    latency = CertainLatency(1),
629    vconfigWakeUp = true,
630    maskWakeUp = true,
631    destDataBits = 128,
632    exceptionOut = Seq(illegalInstr),
633    needSrcFrm = true,
634  )
635
636  val VfmaCfg = FuConfig (
637    name = "vfma",
638    fuType = FuType.vfma,
639    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFMA(cfg)(p).suggestName("Vfma")),
640    srcData = Seq(
641      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
642    ),
643    piped = true,
644    writeVecRf = true,
645    writeV0Rf = true,
646    writeFflags = true,
647    latency = CertainLatency(3),
648    vconfigWakeUp = true,
649    maskWakeUp = true,
650    destDataBits = 128,
651    exceptionOut = Seq(illegalInstr),
652    needSrcFrm = true,
653  )
654
655  val VfdivCfg = FuConfig(
656    name = "vfdiv",
657    fuType = FuType.vfdiv,
658    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VFDivSqrt(cfg)(p).suggestName("Vfdiv")),
659    srcData = Seq(
660      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
661    ),
662    piped = false,
663    writeVecRf = true,
664    writeV0Rf = true,
665    writeFflags = true,
666    latency = UncertainLatency(),
667    vconfigWakeUp = true,
668    maskWakeUp = true,
669    destDataBits = 128,
670    exceptionOut = Seq(illegalInstr),
671    needSrcFrm = true,
672  )
673
674  val VfcvtCfg = FuConfig(
675    name = "vfcvt",
676    fuType = FuType.vfcvt,
677    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VCVT(cfg)(p).suggestName("Vfcvt")),
678    srcData = Seq(
679      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), // vs1, vs2, vd_old, v0, vtype&vl
680    ),
681    piped = true,
682    writeVecRf = true,
683    writeV0Rf = true,
684    writeFflags = true,
685    latency = CertainLatency(2),
686    vconfigWakeUp = true,
687    maskWakeUp = true,
688    destDataBits = 128,
689    exceptionOut = Seq(illegalInstr),
690    needSrcFrm = true,
691  )
692
693  val FaluCfg = FuConfig(
694    name = "falu",
695    fuType = FuType.falu,
696    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FAlu(cfg)(p).suggestName("Falu")),
697    srcData = Seq(
698      Seq(FpData(), FpData()),
699    ),
700    piped = true,
701    writeFpRf = true,
702    writeIntRf = true,
703    writeFflags = true,
704    latency = CertainLatency(1),
705    destDataBits = 64,
706    needSrcFrm = true,
707  )
708
709  val FmacCfg = FuConfig(
710    name = "fmac",
711    fuType = FuType.fmac,
712    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("Fmac")),
713    srcData = Seq(
714      Seq(FpData(), FpData(), FpData()),
715    ),
716    piped = true,
717    writeFpRf = true,
718    writeFflags = true,
719    latency = CertainLatency(3),
720    destDataBits = 64,
721    needSrcFrm = true,
722  )
723
724  val FdivCfg = FuConfig(
725    name = "fdiv",
726    fuType = FuType.fDivSqrt,
727    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("Fdiv")),
728    srcData = Seq(
729      Seq(FpData(), FpData()),
730    ),
731    piped = false,
732    writeFpRf = true,
733    writeFflags = true,
734    latency = UncertainLatency(),
735    destDataBits = 64,
736    needSrcFrm = true,
737  )
738
739  val FcvtCfg = FuConfig(
740    name = "fcvt",
741    fuType = FuType.fcvt,
742    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FCVT(cfg)(p).suggestName("Fcvt")),
743    srcData = Seq(
744      Seq(FpData()),
745    ),
746    piped = true,
747    writeFpRf = true,
748    writeIntRf = true,
749    writeFflags = true,
750    latency = CertainLatency(2),
751    destDataBits = 64,
752    needSrcFrm = true,
753  )
754
755  val VlduCfg: FuConfig = FuConfig (
756    name = "vldu",
757    fuType = FuType.vldu,
758    fuGen = null,
759    srcData = Seq(
760      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  //vs1, vs2, vd_old, v0, vconfig
761    ),
762    piped = false, // Todo: check it
763    writeVecRf = true,
764    writeV0Rf = true,
765    writeVlRf = true,
766    latency = UncertainLatency(),
767    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault, breakPoint),
768    flushPipe = true,
769    replayInst = true,
770    trigger = true,
771    hasLoadError = true,
772    vconfigWakeUp = true,
773    maskWakeUp = true,
774    destDataBits = 128,
775  )
776
777  val VstuCfg: FuConfig = FuConfig (
778    name = "vstu",
779    fuType = FuType.vstu,
780    fuGen = null,
781    srcData = Seq(
782      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()),  //vs1, vs2, vd_old, v0, vconfig
783    ),
784    piped = false,
785    latency = UncertainLatency(),
786    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault, breakPoint),
787    flushPipe = true,
788    replayInst = true,
789    trigger = true,
790    hasLoadError = true,
791    vconfigWakeUp = true,
792    maskWakeUp = true,
793    destDataBits = 128,
794  )
795
796  val VseglduSeg: FuConfig = FuConfig (
797    name = "vsegldu",
798    fuType = FuType.vsegldu,
799    fuGen = null,
800    srcData = Seq(
801      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), //vs1, vs2, vd_old, v0, vconfig
802    ),
803    piped = false, // Todo: check it
804    writeVecRf = true,
805    writeV0Rf = true,
806    writeVlRf = true,
807    latency = UncertainLatency(),
808    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, breakPoint),
809    flushPipe = true,
810    replayInst = true,
811    trigger = true,
812    hasLoadError = true,
813    vconfigWakeUp = true,
814    maskWakeUp = true,
815    destDataBits = 128,
816  )
817
818  val VsegstuCfg: FuConfig = FuConfig(
819    name = "vsegstu",
820    fuType = FuType.vsegstu,
821    fuGen = null,
822    srcData = Seq(
823      Seq(VecData(), VecData(), VecData(), V0Data(), VlData()), //vs1, vs2, vd_old, v0, vconfig
824    ),
825    piped = false,
826    latency = UncertainLatency(),
827    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, breakPoint),
828    flushPipe = true,
829    replayInst = true,
830    trigger = true,
831    hasLoadError = true,
832    vconfigWakeUp = true,
833    maskWakeUp = true,
834    destDataBits = 128,
835  )
836
837  def allConfigs = Seq(
838    JmpCfg, BrhCfg, I2fCfg, I2vCfg, F2vCfg, CsrCfg, AluCfg, MulCfg, DivCfg, FenceCfg, BkuCfg, VSetRvfWvfCfg, VSetRiWvfCfg, VSetRiWiCfg,
839    LduCfg, StaCfg, StdCfg, MouCfg, MoudCfg, VialuCfg, VipuCfg, VlduCfg, VstuCfg, VseglduSeg, VsegstuCfg,
840    FaluCfg, FmacCfg, FcvtCfg, FdivCfg,
841    VfaluCfg, VfmaCfg, VfcvtCfg, HyldaCfg, HystaCfg
842  )
843
844  def VecArithFuConfigs = Seq(
845    VialuCfg, VimacCfg, VppuCfg, VipuCfg, VfaluCfg, VfmaCfg, VfcvtCfg
846  )
847}
848
849