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