xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FuConfig.scala (revision d91483a658064c7276ee0181b0c527a3e2a7d2ee)
1package xiangshan.backend.fu
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import xiangshan.ExceptionNO._
6import xiangshan.SelImm
7import xiangshan.backend.Std
8import xiangshan.backend.fu.fpu.{FDivSqrt, FMA, FPToFP, FPToInt, IntToFP}
9import xiangshan.backend.fu.wrapper.{Alu, BranchUnit, DivUnit, JumpUnit, MulUnit, VSetFVConfig, VSetIVConfig, VSetIVL}
10import xiangshan.backend.Bundles.ExuInput
11import xiangshan.backend.datapath.DataConfig._
12
13case class FuConfig (
14  name: String,
15  fuType: Int,
16  fuGen: (Parameters, FuConfig) => FuncUnit,
17  srcData: Seq[Seq[DataConfig]],
18  writeIntRf: Boolean,
19  writeFpRf: Boolean,
20  writeVecRf: Boolean = false,
21  writeFflags: Boolean = false,
22  dataBits: Int = 64,
23  latency: HasFuLatency = CertainLatency(0),
24  hasInputBuffer: (Boolean, Int, Boolean) = (false, 0, false),
25  exceptionOut: Seq[Int] = Seq(),
26  hasLoadError: Boolean = false,
27  flushPipe: Boolean = false,
28  replayInst: Boolean = false,
29  trigger: Boolean = false,
30  needSrcFrm: Boolean = false,
31  immType: Set[UInt] = Set(),
32) {
33  def numIntSrc : Int = srcData.map(_.count(x => IntRegSrcDataSet.contains(x))).max
34  def numFpSrc  : Int = srcData.map(_.count(x => FpRegSrcDataSet.contains(x))).max
35  def numVecSrc : Int = srcData.map(_.count(x => VecRegSrcDataSet.contains(x))).max
36  def numVfSrc  : Int = srcData.map(_.count(x => VfRegSrcDataSet.contains(x))).max
37  def numRegSrc : Int = srcData.map(_.count(x => RegSrcDataSet.contains(x))).max
38  def numSrc    : Int = srcData.map(_.length).max
39
40  def readFp: Boolean = numFpSrc > 0
41
42  def fuSel(uop: ExuInput): Bool = {
43    // Don't add more shit here!!!
44    // Todo: add new FuType to distinguish f2i, f2f
45    if (this.fuType == FuType.fmisc) {
46      this.name match {
47        case FuConfig.F2iCfg.name => uop.rfWen.get
48        case FuConfig.F2fCfg.name => uop.fpu.get.fpWen && !uop.fpu.get.div && !uop.fpu.get.sqrt
49      }
50    } else {
51      uop.fuType === this.fuType.U
52    }
53  }
54
55  /**
56    * params(i): data type set of the ith src port
57    * @return
58    */
59  def getRfReadDataCfgSet: Seq[Set[DataConfig]] = {
60    val numSrcMax = srcData.map(_.length).max
61    // make srcData is uniform sized to avoid exception when transpose
62    val alignedSrcData: Seq[Seq[DataConfig]] = srcData.map(x => x ++ Seq.fill(numSrcMax - x.length)(null))
63    alignedSrcData.transpose.map(_.toSet.intersect(RegSrcDataSet))
64  }
65
66  def getSrcDataType(srcIdx: Int): Set[DataConfig] = {
67    srcData
68      .map((x: Seq[DataConfig]) => if(x.isDefinedAt(srcIdx)) Some(x(srcIdx)) else None)
69      .filter(_.nonEmpty)
70      .map(_.get)
71      .toSet
72  }
73
74  def hasNoDataWB: Boolean = {
75    !(writeIntRf || writeFpRf || writeVecRf)
76  }
77
78  def getSrcMaxWidthVec = {
79    getRfReadDataCfgSet.map(_.map(_.dataWidth).max)
80  }
81
82  def genSrcDataVec: Seq[UInt] = {
83    getSrcMaxWidthVec.map(w => UInt(w.W))
84  }
85
86  // csr's redirect is in its exception bundle
87  def hasRedirect: Boolean = Seq(FuType.jmp, FuType.brh).contains(fuType)
88
89  def hasPredecode: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr).contains(fuType)
90
91  def needPc: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr, FuType.fence).contains(fuType)
92
93  def needFPUCtrl: Boolean = {
94    import FuType._
95    Set(fmac, fDivSqrt, fmisc, i2f).contains(fuType)
96  }
97
98  def isMul: Boolean = fuType == FuType.mul
99
100  def isDiv: Boolean = fuType == FuType.div
101
102  def isCsr: Boolean = fuType == FuType.csr
103
104  def isFence: Boolean = fuType == FuType.fence
105}
106
107object FuConfig {
108  val JmpCfg: FuConfig = FuConfig (
109    name = "jmp",
110    fuType = FuType.jmp,
111    fuGen = (p: Parameters, cfg: FuConfig) => Module(new JumpUnit(cfg)(p)).suggestName("jmp"),
112    srcData = Seq(
113      Seq(IntData()), // jal
114    ),
115    writeIntRf = true,
116    writeFpRf = false,
117    immType = Set(SelImm.IMM_I, SelImm.IMM_UJ, SelImm.IMM_U),
118  )
119
120  val BrhCfg: FuConfig = FuConfig (
121    name = "brh",
122    fuType = FuType.brh,
123    fuGen = (p: Parameters, cfg: FuConfig) => Module(new BranchUnit(cfg)(p).suggestName("brh")),
124    srcData = Seq(
125      Seq(IntData(), IntData()),
126    ),
127    writeIntRf = false,
128    writeFpRf = false,
129    immType = Set(SelImm.IMM_SB),
130  )
131
132  val I2fCfg: FuConfig = FuConfig (
133    name = "i2f",
134    FuType.i2f,
135    fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntToFP(cfg)(p).suggestName("i2f")),
136    srcData = Seq(
137      Seq(IntData()),
138    ),
139    writeIntRf = false,
140    writeFpRf = true,
141    writeFflags = true,
142    latency = CertainLatency(2),
143    needSrcFrm = true,
144  )
145
146  val CsrCfg: FuConfig = FuConfig (
147    name = "csr",
148    fuType = FuType.csr,
149    fuGen = (p: Parameters, cfg: FuConfig) => Module(new CSR(cfg)(p).suggestName("csr")),
150    srcData = Seq(
151      Seq(IntData()),
152    ),
153    writeIntRf = true,
154    writeFpRf = false,
155    exceptionOut = Seq(illegalInstr, breakPoint, ecallU, ecallS, ecallM),
156    flushPipe = true
157  )
158
159  val AluCfg: FuConfig = FuConfig (
160    name = "alu",
161    fuType = FuType.alu,
162    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Alu(cfg)(p).suggestName("Alu")),
163    srcData = Seq(
164      Seq(IntData(), IntData()),
165    ),
166    writeIntRf = true,
167    writeFpRf = false,
168    immType = Set(SelImm.IMM_I, SelImm.IMM_U),
169  )
170
171  val MulCfg: FuConfig = FuConfig (
172    name = "mul",
173    fuType = FuType.mul,
174    fuGen = (p: Parameters, cfg: FuConfig) => Module(new MulUnit(cfg)(p).suggestName("Mul")),
175    srcData = Seq(
176      Seq(IntData(), IntData()),
177    ),
178    writeIntRf = true,
179    writeFpRf = false,
180    latency = CertainLatency(2),
181  )
182
183  val DivCfg: FuConfig = FuConfig (
184    name = "div",
185    fuType = FuType.div,
186    fuGen = (p: Parameters, cfg: FuConfig) => Module(new DivUnit(cfg)(p).suggestName("Div")),
187    srcData = Seq(
188      Seq(IntData(), IntData()),
189    ),
190    writeIntRf = true,
191    writeFpRf = false,
192    latency = UncertainLatency(),
193    hasInputBuffer = (true, 4, true)
194  )
195
196  val FenceCfg: FuConfig = FuConfig (
197    name = "fence",
198    FuType.fence,
199    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Fence(cfg)(p).suggestName("Fence")),
200    srcData = Seq(
201      Seq(IntData(), IntData()),
202    ),
203    writeIntRf = false,
204    writeFpRf = false,
205    latency = UncertainLatency(),
206    exceptionOut = Seq(illegalInstr),
207    flushPipe = true
208  )
209
210  // Todo: split it to simple bitmap exu and complex bku
211  val BkuCfg: FuConfig = FuConfig (
212    name = "bku",
213    fuType = FuType.bku,
214    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Bku(cfg)(p).suggestName("Bku")),
215    srcData = Seq(
216      Seq(IntData(), IntData()),
217    ),
218    writeIntRf = true,
219    writeFpRf = false,
220    latency = CertainLatency(1),
221  )
222
223  val VSetFVConfigCfg: FuConfig = FuConfig(
224    name = "vsetfvconfig",
225    fuType = FuType.vsetiwf,
226    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetFVConfig(cfg)(p).suggestName("VSetFVConfig")),
227    srcData = Seq(
228      Seq(FpData(), FpData()),
229    ),
230    writeIntRf = false,
231    writeFpRf = false,
232    writeVecRf = true,
233    latency = CertainLatency(0),
234    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
235  )
236
237  val VSetIVConfigCfg: FuConfig = FuConfig(
238    name = "vsetivconfig",
239    fuType = FuType.vsetiwf,
240    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetIVConfig(cfg)(p).suggestName("VSetIVConfig")),
241    srcData = Seq(
242      Seq(IntData(), IntData()),
243    ),
244    writeIntRf = false,
245    writeFpRf = false,
246    writeVecRf = true,
247    latency = CertainLatency(0),
248    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
249  )
250
251  val VSetIVLCfg: FuConfig = FuConfig(
252    name = "vsetivl",
253    fuType = FuType.vsetiwi,
254    fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetIVL(cfg)(p).suggestName("VSetIVL")),
255    srcData = Seq(
256      Seq(IntData(), IntData()),
257    ),
258    writeIntRf = true,
259    writeFpRf = false,
260    latency = CertainLatency(0),
261    immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI),
262  )
263
264  val FmacCfg: FuConfig = FuConfig (
265    name = "fmac",
266    fuType = FuType.fmac,
267    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("FMac")),
268    srcData = Seq(
269      Seq(FpData(), FpData()),
270      Seq(FpData(), FpData(), FpData()),
271    ),
272    writeIntRf = false,
273    writeFpRf = true,
274    writeFflags = true,
275    latency = UncertainLatency(),
276    needSrcFrm = true,
277  )
278
279  val F2iCfg: FuConfig = FuConfig (
280    name = "f2i",
281    fuType = FuType.fmisc,
282    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToInt(cfg)(p).suggestName("F2i")),
283    srcData = Seq(
284      Seq(FpData(), FpData()),
285      Seq(FpData()),
286    ),
287    writeIntRf = true,
288    writeFpRf = false,
289    writeFflags = true,
290    latency = CertainLatency(2),
291    needSrcFrm = true,
292  )
293
294  val F2fCfg: FuConfig = FuConfig (
295    name = "f2f",
296    fuType = FuType.fmisc,
297    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToFP(cfg)(p).suggestName("F2f")),
298    srcData = Seq(
299      Seq(FpData(), FpData()),
300      Seq(FpData()),
301    ),
302    writeIntRf = false,
303    writeFpRf = true,
304    writeFflags = true,
305    latency = CertainLatency(2),
306    needSrcFrm = true,
307  )
308
309  val FDivSqrtCfg: FuConfig = FuConfig (
310    name = "fDivSqrt",
311    fuType = FuType.fDivSqrt,
312    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("FDivSqrt")),
313    srcData = Seq(
314      Seq(FpData(), FpData()),
315    ),
316    writeIntRf = false,
317    writeFpRf = true,
318    writeFflags = true,
319    latency = UncertainLatency(),
320    hasInputBuffer = (true, 8, true),
321    needSrcFrm = true,
322  )
323
324  val LduCfg: FuConfig = FuConfig (
325    name = "ldu",
326    fuType = FuType.ldu,
327    fuGen = null, // Todo
328    srcData = Seq(
329      Seq(IntData()),
330    ),
331    writeIntRf = true,
332    writeFpRf = true,
333    latency = UncertainLatency(),
334    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault),
335    flushPipe = true,
336    replayInst = true,
337    hasLoadError = true,
338    immType = Set(SelImm.IMM_I),
339  )
340
341  val StaCfg: FuConfig = FuConfig (
342    name = "sta",
343    fuType = FuType.stu,
344    fuGen = null, // Todo
345    srcData = Seq(
346      Seq(IntData()),
347    ),
348    writeIntRf = false,
349    writeFpRf = false,
350    latency = UncertainLatency(),
351    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault),
352    immType = Set(SelImm.IMM_S),
353  )
354
355  val StdCfg: FuConfig = FuConfig (
356    name = "std",
357    fuType = FuType.stu,
358    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")),
359    srcData = Seq(
360      Seq(IntData()),
361      Seq(FpData()),
362    ),
363    writeIntRf = false,
364    writeFpRf = false,
365    latency = CertainLatency(1),
366    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault)
367  )
368
369  val MouCfg: FuConfig = FuConfig (
370    name = "mou",
371    fuType = FuType.mou,
372    fuGen = null, // Todo
373    srcData = Seq(
374      Seq(IntData()),
375    ),
376    writeIntRf = true,
377    writeFpRf = false,
378    latency = UncertainLatency(),
379    exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct
380  )
381
382  val MoudCfg: FuConfig = FuConfig (
383    name = "moud",
384    fuType = FuType.mou,
385    fuGen = null, // Todo
386    srcData = Seq(
387      Seq(IntData()),
388    ),
389    writeIntRf = false,
390    writeFpRf = false,
391    latency = UncertainLatency()
392  )
393
394  val VipuCfg: FuConfig = FuConfig (
395    name = "vipu",
396    fuType = FuType.vipu,
397    fuGen = null, // Todo
398    srcData = Seq(
399      Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()),  // vs1, vs2, vd_old, v0
400      Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()),      // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta
401    ),
402    writeIntRf = false,
403    writeFpRf = false,
404    writeVecRf = true,
405    latency = UncertainLatency(),
406  )
407
408  val VfpuCfg: FuConfig = FuConfig (
409    name = "vfpu",
410    fuType = FuType.vfpu,
411    fuGen = null, // Todo
412    srcData = Seq(
413      Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()),  // vs1, vs2, vd_old, v0
414      Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()),      // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta
415      Seq(FpData(), VecData(), VecData(), MaskSrcData(), VConfigData()),   // f[rs1], vs2, vd_old, v0
416    ),
417    writeIntRf = false,
418    writeFpRf = false,
419    writeVecRf = true,
420    latency = UncertainLatency(),
421  )
422  // Todo
423  // def VlduCfg = FuConfig ()
424  // def VstuCfg = FuConfig ()
425
426}
427
428