xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FuConfig.scala (revision 730cfbc0bf03569aa07dd82ba3fb41eb7413e13c)
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}
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 VsetCfg: FuConfig = FuConfig (
224    name = "vset",
225    fuType = FuType.vset,
226    fuGen = null, // Todo
227    srcData = Seq(
228      Seq(IntData(), IntData()),
229    ),
230    writeIntRf = true,
231    writeFpRf = false,
232    latency = CertainLatency(0)
233  )
234
235  val FmacCfg: FuConfig = FuConfig (
236    name = "fmac",
237    fuType = FuType.fmac,
238    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("FMac")),
239    srcData = Seq(
240      Seq(FpData(), FpData()),
241      Seq(FpData(), FpData(), FpData()),
242    ),
243    writeIntRf = false,
244    writeFpRf = true,
245    writeFflags = true,
246    latency = UncertainLatency(),
247    needSrcFrm = true,
248  )
249
250  val F2iCfg: FuConfig = FuConfig (
251    name = "f2i",
252    fuType = FuType.fmisc,
253    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToInt(cfg)(p).suggestName("F2i")),
254    srcData = Seq(
255      Seq(FpData(), FpData()),
256      Seq(FpData()),
257    ),
258    writeIntRf = true,
259    writeFpRf = false,
260    writeFflags = true,
261    latency = CertainLatency(2),
262    needSrcFrm = true,
263  )
264
265  val F2fCfg: FuConfig = FuConfig (
266    name = "f2f",
267    fuType = FuType.fmisc,
268    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToFP(cfg)(p).suggestName("F2f")),
269    srcData = Seq(
270      Seq(FpData(), FpData()),
271      Seq(FpData()),
272    ),
273    writeIntRf = false,
274    writeFpRf = true,
275    writeFflags = true,
276    latency = CertainLatency(2),
277    needSrcFrm = true,
278  )
279
280  val FDivSqrtCfg: FuConfig = FuConfig (
281    name = "fDivSqrt",
282    fuType = FuType.fDivSqrt,
283    fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("FDivSqrt")),
284    srcData = Seq(
285      Seq(FpData(), FpData()),
286    ),
287    writeIntRf = false,
288    writeFpRf = true,
289    writeFflags = true,
290    latency = UncertainLatency(),
291    hasInputBuffer = (true, 8, true),
292    needSrcFrm = true,
293  )
294
295  val LduCfg: FuConfig = FuConfig (
296    name = "ldu",
297    fuType = FuType.ldu,
298    fuGen = null, // Todo
299    srcData = Seq(
300      Seq(IntData()),
301    ),
302    writeIntRf = true,
303    writeFpRf = true,
304    latency = UncertainLatency(),
305    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault),
306    flushPipe = true,
307    replayInst = true,
308    hasLoadError = true,
309    immType = Set(SelImm.IMM_I),
310  )
311
312  val StaCfg: FuConfig = FuConfig (
313    name = "sta",
314    fuType = FuType.stu,
315    fuGen = null, // Todo
316    srcData = Seq(
317      Seq(IntData()),
318    ),
319    writeIntRf = false,
320    writeFpRf = false,
321    latency = UncertainLatency(),
322    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault),
323    immType = Set(SelImm.IMM_S),
324  )
325
326  val StdCfg: FuConfig = FuConfig (
327    name = "std",
328    fuType = FuType.stu,
329    fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")),
330    srcData = Seq(
331      Seq(IntData()),
332      Seq(FpData()),
333    ),
334    writeIntRf = false,
335    writeFpRf = false,
336    latency = CertainLatency(1),
337    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault)
338  )
339
340  val MouCfg: FuConfig = FuConfig (
341    name = "mou",
342    fuType = FuType.mou,
343    fuGen = null, // Todo
344    srcData = Seq(
345      Seq(IntData()),
346    ),
347    writeIntRf = false,
348    writeFpRf = false,
349    latency = UncertainLatency(),
350    exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct
351  )
352
353  val MoudCfg: FuConfig = FuConfig (
354    name = "moud",
355    fuType = FuType.mou,
356    fuGen = null, // Todo
357    srcData = Seq(
358      Seq(IntData()),
359    ),
360    writeIntRf = false,
361    writeFpRf = false,
362    latency = UncertainLatency()
363  )
364
365  val VipuCfg: FuConfig = FuConfig (
366    name = "vipu",
367    fuType = FuType.vipu,
368    fuGen = null, // Todo
369    srcData = Seq(
370      Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()),  // vs1, vs2, vd_old, v0
371      Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()),      // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta
372    ),
373    writeIntRf = false,
374    writeFpRf = false,
375    writeVecRf = true,
376    latency = UncertainLatency(),
377  )
378
379  val VfpuCfg: FuConfig = FuConfig (
380    name = "vfpu",
381    fuType = FuType.vfpu,
382    fuGen = null, // Todo
383    srcData = Seq(
384      Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()),  // vs1, vs2, vd_old, v0
385      Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()),      // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta
386      Seq(FpData(), VecData(), VecData(), MaskSrcData(), VConfigData()),   // f[rs1], vs2, vd_old, v0
387    ),
388    writeIntRf = false,
389    writeFpRf = false,
390    writeVecRf = true,
391    latency = UncertainLatency(),
392  )
393  // Todo
394  // def VlduCfg = FuConfig ()
395  // def VstuCfg = FuConfig ()
396
397}
398
399