xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision 45f43e6e5f88874a7573ff096d1e5c2855bd16c7)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17import chisel3._
18import chisel3.util._
19import org.chipsalliance.cde.config.Parameters
20import freechips.rocketchip.tile.XLen
21import xiangshan.ExceptionNO._
22import xiangshan.backend.fu._
23import xiangshan.backend.fu.fpu._
24import xiangshan.backend.exu._
25import xiangshan.backend.Std
26
27package object xiangshan {
28  object SrcType {
29    def reg = "b00".U
30    def pc  = "b01".U
31    def imm = "b01".U
32    def fp  = "b10".U
33
34    def DC  = imm // Don't Care
35    def X   = BitPat("b??")
36
37    def isReg(srcType: UInt) = srcType===reg
38    def isPc(srcType: UInt) = srcType===pc
39    def isImm(srcType: UInt) = srcType===imm
40    def isFp(srcType: UInt) = srcType(1)
41    def isPcOrImm(srcType: UInt) = srcType(0)
42    def isRegOrFp(srcType: UInt) = !srcType(0)
43    def regIsFp(srcType: UInt) = srcType(1)
44
45    def apply() = UInt(2.W)
46  }
47
48  object SrcState {
49    def busy    = "b0".U
50    def rdy     = "b1".U
51    // def specRdy = "b10".U // speculative ready, for future use
52    def apply() = UInt(1.W)
53  }
54
55  object FuType {
56    def jmp          = "b0000".U
57    def i2f          = "b0001".U
58    def csr          = "b0010".U
59    def alu          = "b0110".U
60    def mul          = "b0100".U
61    def div          = "b0101".U
62    def fence        = "b0011".U
63    def bku          = "b0111".U
64
65    def fmac         = "b1000".U
66    def fmisc        = "b1011".U
67    def fDivSqrt     = "b1010".U
68
69    def ldu          = "b1100".U
70    def stu          = "b1101".U
71    def mou          = "b1111".U // for amo, lr, sc
72
73    def X            = BitPat("b????")
74
75    def num = 14
76
77    def apply() = UInt(log2Up(num).W)
78
79    def isIntExu(fuType: UInt) = !fuType(3)
80    def isJumpExu(fuType: UInt) = fuType === jmp
81    def isFpExu(fuType: UInt) = fuType(3, 2) === "b10".U
82    def isMemExu(fuType: UInt) = fuType(3, 2) === "b11".U
83    def isLoadStore(fuType: UInt) = isMemExu(fuType) && !fuType(1)
84    def isStoreExu(fuType: UInt) = isMemExu(fuType) && fuType(0)
85    def isAMO(fuType: UInt) = fuType(1)
86    def isFence(fuType: UInt) = fuType === fence
87    def isDivSqrt(fuType: UInt) = fuType === div || fuType === fDivSqrt
88    def isSvinvalBegin(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.nofence && !flush
89    def isSvinval(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.sfence && !flush
90    def isSvinvalEnd(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.nofence && flush
91
92
93    def jmpCanAccept(fuType: UInt) = !fuType(2)
94    def mduCanAccept(fuType: UInt) = fuType(2) && !fuType(1) || fuType(2) && fuType(1) && fuType(0)
95    def aluCanAccept(fuType: UInt) = fuType(2) && fuType(1) && !fuType(0)
96
97    def fmacCanAccept(fuType: UInt) = !fuType(1)
98    def fmiscCanAccept(fuType: UInt) = fuType(1)
99
100    def loadCanAccept(fuType: UInt) = !fuType(0)
101    def storeCanAccept(fuType: UInt) = fuType(0)
102
103    def storeIsAMO(fuType: UInt) = fuType(1)
104
105    val functionNameMap = Map(
106      jmp.litValue -> "jmp",
107      i2f.litValue -> "int_to_float",
108      csr.litValue -> "csr",
109      alu.litValue -> "alu",
110      mul.litValue -> "mul",
111      div.litValue -> "div",
112      fence.litValue -> "fence",
113      bku.litValue -> "bku",
114      fmac.litValue -> "fmac",
115      fmisc.litValue -> "fmisc",
116      fDivSqrt.litValue -> "fdiv_fsqrt",
117      ldu.litValue -> "load",
118      stu.litValue -> "store",
119      mou.litValue -> "mou"
120    )
121  }
122
123  object FuOpType {
124    def apply() = UInt(7.W)
125    def X = BitPat("b???????")
126  }
127
128  object CommitType {
129    def NORMAL = "b000".U  // int/fp
130    def BRANCH = "b001".U  // branch
131    def LOAD   = "b010".U  // load
132    def STORE  = "b011".U  // store
133
134    def apply() = UInt(3.W)
135    def isFused(commitType: UInt): Bool = commitType(2)
136    def isLoadStore(commitType: UInt): Bool = !isFused(commitType) && commitType(1)
137    def lsInstIsStore(commitType: UInt): Bool = commitType(0)
138    def isStore(commitType: UInt): Bool = isLoadStore(commitType) && lsInstIsStore(commitType)
139    def isBranch(commitType: UInt): Bool = commitType(0) && !commitType(1) && !isFused(commitType)
140  }
141
142  object RedirectLevel {
143    def flushAfter = "b0".U
144    def flush      = "b1".U
145
146    def apply() = UInt(1.W)
147    // def isUnconditional(level: UInt) = level(1)
148    def flushItself(level: UInt) = level(0)
149    // def isException(level: UInt) = level(1) && level(0)
150  }
151
152  object ExceptionVec {
153    val ExceptionVecSize = 16
154    def apply() = Vec(ExceptionVecSize, Bool())
155  }
156
157  object PMAMode {
158    def R = "b1".U << 0 //readable
159    def W = "b1".U << 1 //writeable
160    def X = "b1".U << 2 //executable
161    def I = "b1".U << 3 //cacheable: icache
162    def D = "b1".U << 4 //cacheable: dcache
163    def S = "b1".U << 5 //enable speculative access
164    def A = "b1".U << 6 //enable atomic operation, A imply R & W
165    def C = "b1".U << 7 //if it is cacheable is configable
166    def Reserved = "b0".U
167
168    def apply() = UInt(7.W)
169
170    def read(mode: UInt) = mode(0)
171    def write(mode: UInt) = mode(1)
172    def execute(mode: UInt) = mode(2)
173    def icache(mode: UInt) = mode(3)
174    def dcache(mode: UInt) = mode(4)
175    def speculate(mode: UInt) = mode(5)
176    def atomic(mode: UInt) = mode(6)
177    def configable_cache(mode: UInt) = mode(7)
178
179    def strToMode(s: String) = {
180      var result = 0.U(8.W)
181      if (s.toUpperCase.indexOf("R") >= 0) result = result + R
182      if (s.toUpperCase.indexOf("W") >= 0) result = result + W
183      if (s.toUpperCase.indexOf("X") >= 0) result = result + X
184      if (s.toUpperCase.indexOf("I") >= 0) result = result + I
185      if (s.toUpperCase.indexOf("D") >= 0) result = result + D
186      if (s.toUpperCase.indexOf("S") >= 0) result = result + S
187      if (s.toUpperCase.indexOf("A") >= 0) result = result + A
188      if (s.toUpperCase.indexOf("C") >= 0) result = result + C
189      result
190    }
191  }
192
193
194  object CSROpType {
195    def jmp  = "b000".U
196    def wrt  = "b001".U
197    def set  = "b010".U
198    def clr  = "b011".U
199    def wfi  = "b100".U
200    def wrti = "b101".U
201    def seti = "b110".U
202    def clri = "b111".U
203    def needAccess(op: UInt): Bool = op(1, 0) =/= 0.U
204  }
205
206  // jump
207  object JumpOpType {
208    def jal  = "b00".U
209    def jalr = "b01".U
210    def auipc = "b10".U
211//    def call = "b11_011".U
212//    def ret  = "b11_100".U
213    def jumpOpisJalr(op: UInt) = op(0)
214    def jumpOpisAuipc(op: UInt) = op(1)
215  }
216
217  object FenceOpType {
218    def fence  = "b10000".U
219    def sfence = "b10001".U
220    def fencei = "b10010".U
221    def nofence= "b00000".U
222  }
223
224  object ALUOpType {
225    // shift optype
226    def slliuw     = "b000_0000".U // slliuw: ZEXT(src1[31:0]) << shamt
227    def sll        = "b000_0001".U // sll:     src1 << src2
228
229    def bclr       = "b000_0010".U // bclr:    src1 & ~(1 << src2[5:0])
230    def bset       = "b000_0011".U // bset:    src1 | (1 << src2[5:0])
231    def binv       = "b000_0100".U // binv:    src1 ^ ~(1 << src2[5:0])
232
233    def srl        = "b000_0101".U // srl:     src1 >> src2
234    def bext       = "b000_0110".U // bext:    (src1 >> src2)[0]
235    def sra        = "b000_0111".U // sra:     src1 >> src2 (arithmetic)
236
237    def rol        = "b000_1001".U // rol:     (src1 << src2) | (src1 >> (xlen - src2))
238    def ror        = "b000_1011".U // ror:     (src1 >> src2) | (src1 << (xlen - src2))
239
240    // RV64 32bit optype
241    def addw       = "b001_0000".U // addw:      SEXT((src1 + src2)[31:0])
242    def oddaddw    = "b001_0001".U // oddaddw:   SEXT((src1[0] + src2)[31:0])
243    def subw       = "b001_0010".U // subw:      SEXT((src1 - src2)[31:0])
244
245    def addwbit    = "b001_0100".U // addwbit:   (src1 + src2)[0]
246    def addwbyte   = "b001_0101".U // addwbyte:  (src1 + src2)[7:0]
247    def addwzexth  = "b001_0110".U // addwzexth: ZEXT((src1  + src2)[15:0])
248    def addwsexth  = "b001_0111".U // addwsexth: SEXT((src1  + src2)[15:0])
249
250    def sllw       = "b001_1000".U // sllw:     SEXT((src1 << src2)[31:0])
251    def srlw       = "b001_1001".U // srlw:     SEXT((src1[31:0] >> src2)[31:0])
252    def sraw       = "b001_1010".U // sraw:     SEXT((src1[31:0] >> src2)[31:0])
253    def rolw       = "b001_1100".U
254    def rorw       = "b001_1101".U
255
256    // ADD-op
257    def adduw      = "b010_0000".U // adduw:  src1[31:0]  + src2
258    def add        = "b010_0001".U // add:     src1        + src2
259    def oddadd     = "b010_0010".U // oddadd:  src1[0]     + src2
260
261    def sr29add    = "b010_0100".U // sr29add: src1[63:29] + src2
262    def sr30add    = "b010_0101".U // sr30add: src1[63:30] + src2
263    def sr31add    = "b010_0110".U // sr31add: src1[63:31] + src2
264    def sr32add    = "b010_0111".U // sr32add: src1[63:32] + src2
265
266    def sh1adduw   = "b010_1000".U // sh1adduw: {src1[31:0], 1'b0} + src2
267    def sh1add     = "b010_1001".U // sh1add: {src1[62:0], 1'b0} + src2
268    def sh2adduw   = "b010_1010".U // sh2add_uw: {src1[31:0], 2'b0} + src2
269    def sh2add     = "b010_1011".U // sh2add: {src1[61:0], 2'b0} + src2
270    def sh3adduw   = "b010_1100".U // sh3add_uw: {src1[31:0], 3'b0} + src2
271    def sh3add     = "b010_1101".U // sh3add: {src1[60:0], 3'b0} + src2
272    def sh4add     = "b010_1111".U // sh4add: {src1[59:0], 4'b0} + src2
273
274    // SUB-op: src1 - src2
275    def sub        = "b011_0000".U
276    def sltu       = "b011_0001".U
277    def slt        = "b011_0010".U
278    def maxu       = "b011_0100".U
279    def minu       = "b011_0101".U
280    def max        = "b011_0110".U
281    def min        = "b011_0111".U
282
283    // branch
284    def beq        = "b111_0000".U
285    def bne        = "b111_0010".U
286    def blt        = "b111_1000".U
287    def bge        = "b111_1010".U
288    def bltu       = "b111_1100".U
289    def bgeu       = "b111_1110".U
290
291    // misc optype
292    def and        = "b100_0000".U
293    def andn       = "b100_0001".U
294    def or         = "b100_0010".U
295    def orn        = "b100_0011".U
296    def xor        = "b100_0100".U
297    def xnor       = "b100_0101".U
298    def orcb       = "b100_0110".U
299
300    def sextb      = "b100_1000".U
301    def packh      = "b100_1001".U
302    def sexth      = "b100_1010".U
303    def packw      = "b100_1011".U
304
305    def revb       = "b101_0000".U
306    def rev8       = "b101_0001".U
307    def pack       = "b101_0010".U
308    def orh48      = "b101_0011".U
309
310    def szewl1     = "b101_1000".U
311    def szewl2     = "b101_1001".U
312    def szewl3     = "b101_1010".U
313    def byte2      = "b101_1011".U
314
315    def andlsb     = "b110_0000".U
316    def andzexth   = "b110_0001".U
317    def orlsb      = "b110_0010".U
318    def orzexth    = "b110_0011".U
319    def xorlsb     = "b110_0100".U
320    def xorzexth   = "b110_0101".U
321    def orcblsb    = "b110_0110".U
322    def orcbzexth  = "b110_0111".U
323
324    def isAddw(func: UInt) = func(6, 4) === "b001".U && !func(3) && !func(1)
325    def isSimpleLogic(func: UInt) = func(6, 4) === "b100".U && !func(0)
326    def logicToLsb(func: UInt) = Cat("b110".U(3.W), func(3, 1), 0.U(1.W))
327    def logicToZexth(func: UInt) = Cat("b110".U(3.W), func(3, 1), 1.U(1.W))
328    def isBranch(func: UInt) = func(6, 4) === "b111".U
329    def getBranchType(func: UInt) = func(3, 2)
330    def isBranchInvert(func: UInt) = func(1)
331
332    def apply() = UInt(7.W)
333  }
334
335  object MDUOpType {
336    // mul
337    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
338    def mul    = "b00000".U
339    def mulh   = "b00001".U
340    def mulhsu = "b00010".U
341    def mulhu  = "b00011".U
342    def mulw   = "b00100".U
343
344    def mulw7  = "b01100".U
345
346    // div
347    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
348    def div    = "b10000".U
349    def divu   = "b10010".U
350    def rem    = "b10001".U
351    def remu   = "b10011".U
352
353    def divw   = "b10100".U
354    def divuw  = "b10110".U
355    def remw   = "b10101".U
356    def remuw  = "b10111".U
357
358    def isMul(op: UInt) = !op(4)
359    def isDiv(op: UInt) = op(4)
360
361    def isDivSign(op: UInt) = isDiv(op) && !op(1)
362    def isW(op: UInt) = op(2)
363    def isH(op: UInt) = (isDiv(op) && op(0)) || (isMul(op) && op(1, 0) =/= 0.U)
364    def getMulOp(op: UInt) = op(1, 0)
365  }
366
367  object LSUOpType {
368    // load pipeline
369
370    // normal load
371    // Note: bit(1, 0) are size, DO NOT CHANGE
372    // bit encoding: | load 0 | is unsigned(1bit) | size(2bit) |
373    def lb       = "b0000".U
374    def lh       = "b0001".U
375    def lw       = "b0010".U
376    def ld       = "b0011".U
377    def lbu      = "b0100".U
378    def lhu      = "b0101".U
379    def lwu      = "b0110".U
380
381    // Zicbop software prefetch
382    // bit encoding: | prefetch 1 | 0 | prefetch type (2bit) |
383    def prefetch_i = "b1000".U // TODO
384    def prefetch_r = "b1001".U
385    def prefetch_w = "b1010".U
386
387    def isPrefetch(op: UInt): Bool = op(3)
388
389    // store pipeline
390    // normal store
391    // bit encoding: | store 00 | size(2bit) |
392    def sb       = "b0000".U
393    def sh       = "b0001".U
394    def sw       = "b0010".U
395    def sd       = "b0011".U
396
397    // l1 cache op
398    // bit encoding: | cbo_zero 01 | size(2bit) 11 |
399    def cbo_zero  = "b0111".U
400
401    // llc op
402    // bit encoding: | prefetch 11 | suboptype(2bit) |
403    def cbo_clean = "b1100".U
404    def cbo_flush = "b1101".U
405    def cbo_inval = "b1110".U
406
407    def isCbo(op: UInt): Bool = op(3, 2) === "b11".U
408
409    // atomics
410    // bit(1, 0) are size
411    // since atomics use a different fu type
412    // so we can safely reuse other load/store's encodings
413    // bit encoding: | optype(4bit) | size (2bit) |
414    def lr_w      = "b000010".U
415    def sc_w      = "b000110".U
416    def amoswap_w = "b001010".U
417    def amoadd_w  = "b001110".U
418    def amoxor_w  = "b010010".U
419    def amoand_w  = "b010110".U
420    def amoor_w   = "b011010".U
421    def amomin_w  = "b011110".U
422    def amomax_w  = "b100010".U
423    def amominu_w = "b100110".U
424    def amomaxu_w = "b101010".U
425
426    def lr_d      = "b000011".U
427    def sc_d      = "b000111".U
428    def amoswap_d = "b001011".U
429    def amoadd_d  = "b001111".U
430    def amoxor_d  = "b010011".U
431    def amoand_d  = "b010111".U
432    def amoor_d   = "b011011".U
433    def amomin_d  = "b011111".U
434    def amomax_d  = "b100011".U
435    def amominu_d = "b100111".U
436    def amomaxu_d = "b101011".U
437
438    def size(op: UInt) = op(1,0)
439  }
440
441  object BKUOpType {
442
443    def clmul       = "b000000".U
444    def clmulh      = "b000001".U
445    def clmulr      = "b000010".U
446    def xpermn      = "b000100".U
447    def xpermb      = "b000101".U
448
449    def clz         = "b001000".U
450    def clzw        = "b001001".U
451    def ctz         = "b001010".U
452    def ctzw        = "b001011".U
453    def cpop        = "b001100".U
454    def cpopw       = "b001101".U
455
456    // 01xxxx is reserve
457    def aes64es     = "b100000".U
458    def aes64esm    = "b100001".U
459    def aes64ds     = "b100010".U
460    def aes64dsm    = "b100011".U
461    def aes64im     = "b100100".U
462    def aes64ks1i   = "b100101".U
463    def aes64ks2    = "b100110".U
464
465    // merge to two instruction sm4ks & sm4ed
466    def sm4ed0      = "b101000".U
467    def sm4ed1      = "b101001".U
468    def sm4ed2      = "b101010".U
469    def sm4ed3      = "b101011".U
470    def sm4ks0      = "b101100".U
471    def sm4ks1      = "b101101".U
472    def sm4ks2      = "b101110".U
473    def sm4ks3      = "b101111".U
474
475    def sha256sum0  = "b110000".U
476    def sha256sum1  = "b110001".U
477    def sha256sig0  = "b110010".U
478    def sha256sig1  = "b110011".U
479    def sha512sum0  = "b110100".U
480    def sha512sum1  = "b110101".U
481    def sha512sig0  = "b110110".U
482    def sha512sig1  = "b110111".U
483
484    def sm3p0       = "b111000".U
485    def sm3p1       = "b111001".U
486  }
487
488  object BTBtype {
489    def B = "b00".U  // branch
490    def J = "b01".U  // jump
491    def I = "b10".U  // indirect
492    def R = "b11".U  // return
493
494    def apply() = UInt(2.W)
495  }
496
497  object SelImm {
498    def IMM_X  = "b0111".U
499    def IMM_S  = "b0000".U
500    def IMM_SB = "b0001".U
501    def IMM_U  = "b0010".U
502    def IMM_UJ = "b0011".U
503    def IMM_I  = "b0100".U
504    def IMM_Z  = "b0101".U
505    def INVALID_INSTR = "b0110".U
506    def IMM_B6 = "b1000".U
507
508    def X      = BitPat("b????")
509
510    def apply() = UInt(4.W)
511  }
512
513  object ExceptionNO {
514    def instrAddrMisaligned = 0
515    def instrAccessFault    = 1
516    def illegalInstr        = 2
517    def breakPoint          = 3
518    def loadAddrMisaligned  = 4
519    def loadAccessFault     = 5
520    def storeAddrMisaligned = 6
521    def storeAccessFault    = 7
522    def ecallU              = 8
523    def ecallS              = 9
524    def ecallM              = 11
525    def instrPageFault      = 12
526    def loadPageFault       = 13
527    // def singleStep          = 14
528    def storePageFault      = 15
529    def priorities = Seq(
530      breakPoint, // TODO: different BP has different priority
531      instrPageFault,
532      instrAccessFault,
533      illegalInstr,
534      instrAddrMisaligned,
535      ecallM, ecallS, ecallU,
536      storeAddrMisaligned,
537      loadAddrMisaligned,
538      storePageFault,
539      loadPageFault,
540      storeAccessFault,
541      loadAccessFault
542    )
543    def all = priorities.distinct.sorted
544    def frontendSet = Seq(
545      instrAddrMisaligned,
546      instrAccessFault,
547      illegalInstr,
548      instrPageFault
549    )
550    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
551      val new_vec = Wire(ExceptionVec())
552      new_vec.foreach(_ := false.B)
553      select.foreach(i => new_vec(i) := vec(i))
554      new_vec
555    }
556    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
557    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
558    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
559      partialSelect(vec, fuConfig.exceptionOut)
560    def selectByExu(vec:Vec[Bool], exuConfig: ExuConfig): Vec[Bool] =
561      partialSelect(vec, exuConfig.exceptionOut)
562    def selectByExu(vec:Vec[Bool], exuConfigs: Seq[ExuConfig]): Vec[Bool] =
563      partialSelect(vec, exuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted)
564  }
565
566  def dividerGen(p: Parameters) = new DividerWrapper(p(XLen))(p)
567  def multiplierGen(p: Parameters) = new ArrayMultiplier(p(XLen) + 1)(p)
568  def aluGen(p: Parameters) = new Alu()(p)
569  def bkuGen(p: Parameters) = new Bku()(p)
570  def jmpGen(p: Parameters) = new Jump()(p)
571  def fenceGen(p: Parameters) = new Fence()(p)
572  def csrGen(p: Parameters) = new CSR()(p)
573  def i2fGen(p: Parameters) = new IntToFP()(p)
574  def fmacGen(p: Parameters) = new FMA()(p)
575  def f2iGen(p: Parameters) = new FPToInt()(p)
576  def f2fGen(p: Parameters) = new FPToFP()(p)
577  def fdivSqrtGen(p: Parameters) = new FDivSqrt()(p)
578  def stdGen(p: Parameters) = new Std()(p)
579  def mouDataGen(p: Parameters) = new Std()(p)
580
581  def f2iSel(uop: MicroOp): Bool = {
582    uop.ctrl.rfWen
583  }
584
585  def i2fSel(uop: MicroOp): Bool = {
586    uop.ctrl.fpu.fromInt
587  }
588
589  def f2fSel(uop: MicroOp): Bool = {
590    val ctrl = uop.ctrl.fpu
591    ctrl.fpWen && !ctrl.div && !ctrl.sqrt
592  }
593
594  def fdivSqrtSel(uop: MicroOp): Bool = {
595    val ctrl = uop.ctrl.fpu
596    ctrl.div || ctrl.sqrt
597  }
598
599  val aluCfg = FuConfig(
600    name = "alu",
601    fuGen = aluGen,
602    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.alu,
603    fuType = FuType.alu,
604    numIntSrc = 2,
605    numFpSrc = 0,
606    writeIntRf = true,
607    writeFpRf = false,
608    hasRedirect = true,
609  )
610
611  val jmpCfg = FuConfig(
612    name = "jmp",
613    fuGen = jmpGen,
614    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.jmp,
615    fuType = FuType.jmp,
616    numIntSrc = 1,
617    numFpSrc = 0,
618    writeIntRf = true,
619    writeFpRf = false,
620    hasRedirect = true,
621  )
622
623  val fenceCfg = FuConfig(
624    name = "fence",
625    fuGen = fenceGen,
626    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.fence,
627    FuType.fence, 2, 0, writeIntRf = false, writeFpRf = false,
628    latency = UncertainLatency(), exceptionOut = Seq(illegalInstr), // TODO: need rewrite latency structure, not just this value,
629    flushPipe = true
630  )
631
632  val csrCfg = FuConfig(
633    name = "csr",
634    fuGen = csrGen,
635    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.csr,
636    fuType = FuType.csr,
637    numIntSrc = 1,
638    numFpSrc = 0,
639    writeIntRf = true,
640    writeFpRf = false,
641    exceptionOut = Seq(illegalInstr, breakPoint, ecallU, ecallS, ecallM),
642    flushPipe = true
643  )
644
645  val i2fCfg = FuConfig(
646    name = "i2f",
647    fuGen = i2fGen,
648    fuSel = i2fSel,
649    FuType.i2f,
650    numIntSrc = 1,
651    numFpSrc = 0,
652    writeIntRf = false,
653    writeFpRf = true,
654    writeFflags = true,
655    latency = CertainLatency(2),
656    fastUopOut = true, fastImplemented = true
657  )
658
659  val divCfg = FuConfig(
660    name = "div",
661    fuGen = dividerGen,
662    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.div,
663    FuType.div,
664    2,
665    0,
666    writeIntRf = true,
667    writeFpRf = false,
668    latency = UncertainLatency(),
669    fastUopOut = true,
670    fastImplemented = true,
671    hasInputBuffer = (true, 4, true)
672  )
673
674  val mulCfg = FuConfig(
675    name = "mul",
676    fuGen = multiplierGen,
677    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.mul,
678    FuType.mul,
679    2,
680    0,
681    writeIntRf = true,
682    writeFpRf = false,
683    latency = CertainLatency(2),
684    fastUopOut = true,
685    fastImplemented = true
686  )
687
688  val bkuCfg = FuConfig(
689    name = "bku",
690    fuGen = bkuGen,
691    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.bku,
692    fuType = FuType.bku,
693    numIntSrc = 2,
694    numFpSrc = 0,
695    writeIntRf = true,
696    writeFpRf = false,
697    latency = CertainLatency(1),
698    fastUopOut = true,
699    fastImplemented = true
700 )
701
702  val fmacCfg = FuConfig(
703    name = "fmac",
704    fuGen = fmacGen,
705    fuSel = _ => true.B,
706    FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, writeFflags = true,
707    latency = UncertainLatency(), fastUopOut = true, fastImplemented = true
708  )
709
710  val f2iCfg = FuConfig(
711    name = "f2i",
712    fuGen = f2iGen,
713    fuSel = f2iSel,
714    FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, writeFflags = true, latency = CertainLatency(2),
715    fastUopOut = true, fastImplemented = true
716  )
717
718  val f2fCfg = FuConfig(
719    name = "f2f",
720    fuGen = f2fGen,
721    fuSel = f2fSel,
722    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = CertainLatency(2),
723    fastUopOut = true, fastImplemented = true
724  )
725
726  val fdivSqrtCfg = FuConfig(
727    name = "fdivSqrt",
728    fuGen = fdivSqrtGen,
729    fuSel = fdivSqrtSel,
730    FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = UncertainLatency(),
731    fastUopOut = true, fastImplemented = true, hasInputBuffer = (true, 8, true)
732  )
733
734  val lduCfg = FuConfig(
735    "ldu",
736    null, // DontCare
737    (uop: MicroOp) => FuType.loadCanAccept(uop.ctrl.fuType),
738    FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true,
739    latency = UncertainLatency(),
740    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault),
741    flushPipe = true,
742    replayInst = true,
743    hasLoadError = true
744  )
745
746  val staCfg = FuConfig(
747    "sta",
748    null,
749    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
750    FuType.stu, 1, 0, writeIntRf = false, writeFpRf = false,
751    latency = UncertainLatency(),
752    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault)
753  )
754
755  val stdCfg = FuConfig(
756    "std",
757    fuGen = stdGen, fuSel = (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), FuType.stu, 1, 1,
758    writeIntRf = false, writeFpRf = false, latency = CertainLatency(1)
759  )
760
761  val mouCfg = FuConfig(
762    "mou",
763    null,
764    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
765    FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false,
766    latency = UncertainLatency(), exceptionOut = lduCfg.exceptionOut ++ staCfg.exceptionOut
767  )
768
769  val mouDataCfg = FuConfig(
770    "mou",
771    mouDataGen,
772    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
773    FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false,
774    latency = UncertainLatency()
775  )
776
777  val JumpExeUnitCfg = ExuConfig("JmpExeUnit", "Int", Seq(jmpCfg, i2fCfg), 2, Int.MaxValue)
778  val AluExeUnitCfg = ExuConfig("AluExeUnit", "Int", Seq(aluCfg), 0, Int.MaxValue)
779  val JumpCSRExeUnitCfg = ExuConfig("JmpCSRExeUnit", "Int", Seq(jmpCfg, csrCfg, fenceCfg, i2fCfg), 2, Int.MaxValue)
780  val MulDivExeUnitCfg = ExuConfig("MulDivExeUnit", "Int", Seq(mulCfg, divCfg, bkuCfg), 1, Int.MaxValue)
781  val FmacExeUnitCfg = ExuConfig("FmacExeUnit", "Fp", Seq(fmacCfg), Int.MaxValue, 0)
782  val FmiscExeUnitCfg = ExuConfig(
783    "FmiscExeUnit",
784    "Fp",
785    Seq(f2iCfg, f2fCfg, fdivSqrtCfg),
786    Int.MaxValue, 1
787  )
788  val LdExeUnitCfg = ExuConfig("LoadExu", "Mem", Seq(lduCfg.copy(exceptionOut = mouCfg.exceptionOut)), wbIntPriority = 0, wbFpPriority = 0, extendsExu = false)
789  val StaExeUnitCfg = ExuConfig("StaExu", "Mem", Seq(staCfg, mouCfg.copy(exceptionOut = Seq())), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false)
790  val StdExeUnitCfg = ExuConfig("StdExu", "Mem", Seq(stdCfg, mouDataCfg), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false)
791
792  object TopDownCounters extends Enumeration {
793    val NoStall = Value("NoStall")  // Base
794    // frontend
795    val OverrideBubble = Value("OverrideBubble")
796    val FtqUpdateBubble = Value("FtqUpdateBubble")
797    // val ControlRedirectBubble = Value("ControlRedirectBubble")
798    val TAGEMissBubble = Value("TAGEMissBubble")
799    val SCMissBubble = Value("SCMissBubble")
800    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
801    val RASMissBubble = Value("RASMissBubble")
802    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
803    val OtherRedirectBubble = Value("OtherRedirectBubble")
804    val FtqFullStall = Value("FtqFullStall")
805
806    val ICacheMissBubble = Value("ICacheMissBubble")
807    val ITLBMissBubble = Value("ITLBMissBubble")
808    val BTBMissBubble = Value("BTBMissBubble")
809    val FetchFragBubble = Value("FetchFragBubble")
810
811    // backend
812    // long inst stall at rob head
813    val DivStall = Value("DivStall") // int div, float div/sqrt
814    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
815    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
816    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
817    // freelist full
818    val IntFlStall = Value("IntFlStall")
819    val FpFlStall = Value("FpFlStall")
820    // dispatch queue full
821    val IntDqStall = Value("IntDqStall")
822    val FpDqStall = Value("FpDqStall")
823    val LsDqStall = Value("LsDqStall")
824
825    // memblock
826    val LoadTLBStall = Value("LoadTLBStall")
827    val LoadL1Stall = Value("LoadL1Stall")
828    val LoadL2Stall = Value("LoadL2Stall")
829    val LoadL3Stall = Value("LoadL3Stall")
830    val LoadMemStall = Value("LoadMemStall")
831    val StoreStall = Value("StoreStall") // include store tlb miss
832    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
833
834    // xs replay (different to gem5)
835    val LoadVioReplayStall = Value("LoadVioReplayStall")
836    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
837
838    // bad speculation
839    val ControlRecoveryStall = Value("ControlRecoveryStall")
840    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
841    val OtherRecoveryStall = Value("OtherRecoveryStall")
842
843    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
844
845    val OtherCoreStall = Value("OtherCoreStall")
846
847    val NumStallReasons = Value("NumStallReasons")
848  }
849}
850