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