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