xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision ef6723f9795e8222d080df5d74a2a307c1e68a86)
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 = 24
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 hfence_v = "b10011".U
222    def hfence_g = "b10100".U
223    def nofence= "b00000".U
224  }
225
226  object ALUOpType {
227    // shift optype
228    def slliuw     = "b000_0000".U // slliuw: ZEXT(src1[31:0]) << shamt
229    def sll        = "b000_0001".U // sll:     src1 << src2
230
231    def bclr       = "b000_0010".U // bclr:    src1 & ~(1 << src2[5:0])
232    def bset       = "b000_0011".U // bset:    src1 | (1 << src2[5:0])
233    def binv       = "b000_0100".U // binv:    src1 ^ ~(1 << src2[5:0])
234
235    def srl        = "b000_0101".U // srl:     src1 >> src2
236    def bext       = "b000_0110".U // bext:    (src1 >> src2)[0]
237    def sra        = "b000_0111".U // sra:     src1 >> src2 (arithmetic)
238
239    def rol        = "b000_1001".U // rol:     (src1 << src2) | (src1 >> (xlen - src2))
240    def ror        = "b000_1011".U // ror:     (src1 >> src2) | (src1 << (xlen - src2))
241
242    // RV64 32bit optype
243    def addw       = "b001_0000".U // addw:      SEXT((src1 + src2)[31:0])
244    def oddaddw    = "b001_0001".U // oddaddw:   SEXT((src1[0] + src2)[31:0])
245    def subw       = "b001_0010".U // subw:      SEXT((src1 - src2)[31:0])
246
247    def addwbit    = "b001_0100".U // addwbit:   (src1 + src2)[0]
248    def addwbyte   = "b001_0101".U // addwbyte:  (src1 + src2)[7:0]
249    def addwzexth  = "b001_0110".U // addwzexth: ZEXT((src1  + src2)[15:0])
250    def addwsexth  = "b001_0111".U // addwsexth: SEXT((src1  + src2)[15:0])
251
252    def sllw       = "b001_1000".U // sllw:     SEXT((src1 << src2)[31:0])
253    def srlw       = "b001_1001".U // srlw:     SEXT((src1[31:0] >> src2)[31:0])
254    def sraw       = "b001_1010".U // sraw:     SEXT((src1[31:0] >> src2)[31:0])
255    def rolw       = "b001_1100".U
256    def rorw       = "b001_1101".U
257
258    // ADD-op
259    def adduw      = "b010_0000".U // adduw:  src1[31:0]  + src2
260    def add        = "b010_0001".U // add:     src1        + src2
261    def oddadd     = "b010_0010".U // oddadd:  src1[0]     + src2
262
263    def sr29add    = "b010_0100".U // sr29add: src1[63:29] + src2
264    def sr30add    = "b010_0101".U // sr30add: src1[63:30] + src2
265    def sr31add    = "b010_0110".U // sr31add: src1[63:31] + src2
266    def sr32add    = "b010_0111".U // sr32add: src1[63:32] + src2
267
268    def sh1adduw   = "b010_1000".U // sh1adduw: {src1[31:0], 1'b0} + src2
269    def sh1add     = "b010_1001".U // sh1add: {src1[62:0], 1'b0} + src2
270    def sh2adduw   = "b010_1010".U // sh2add_uw: {src1[31:0], 2'b0} + src2
271    def sh2add     = "b010_1011".U // sh2add: {src1[61:0], 2'b0} + src2
272    def sh3adduw   = "b010_1100".U // sh3add_uw: {src1[31:0], 3'b0} + src2
273    def sh3add     = "b010_1101".U // sh3add: {src1[60:0], 3'b0} + src2
274    def sh4add     = "b010_1111".U // sh4add: {src1[59:0], 4'b0} + src2
275
276    // SUB-op: src1 - src2
277    def sub        = "b011_0000".U
278    def sltu       = "b011_0001".U
279    def slt        = "b011_0010".U
280    def maxu       = "b011_0100".U
281    def minu       = "b011_0101".U
282    def max        = "b011_0110".U
283    def min        = "b011_0111".U
284
285    // branch
286    def beq        = "b111_0000".U
287    def bne        = "b111_0010".U
288    def blt        = "b111_1000".U
289    def bge        = "b111_1010".U
290    def bltu       = "b111_1100".U
291    def bgeu       = "b111_1110".U
292
293    // misc optype
294    def and        = "b100_0000".U
295    def andn       = "b100_0001".U
296    def or         = "b100_0010".U
297    def orn        = "b100_0011".U
298    def xor        = "b100_0100".U
299    def xnor       = "b100_0101".U
300    def orcb       = "b100_0110".U
301
302    def sextb      = "b100_1000".U
303    def packh      = "b100_1001".U
304    def sexth      = "b100_1010".U
305    def packw      = "b100_1011".U
306
307    def revb       = "b101_0000".U
308    def rev8       = "b101_0001".U
309    def pack       = "b101_0010".U
310    def orh48      = "b101_0011".U
311
312    def szewl1     = "b101_1000".U
313    def szewl2     = "b101_1001".U
314    def szewl3     = "b101_1010".U
315    def byte2      = "b101_1011".U
316
317    def andlsb     = "b110_0000".U
318    def andzexth   = "b110_0001".U
319    def orlsb      = "b110_0010".U
320    def orzexth    = "b110_0011".U
321    def xorlsb     = "b110_0100".U
322    def xorzexth   = "b110_0101".U
323    def orcblsb    = "b110_0110".U
324    def orcbzexth  = "b110_0111".U
325
326    def isAddw(func: UInt) = func(6, 4) === "b001".U && !func(3) && !func(1)
327    def isSimpleLogic(func: UInt) = func(6, 4) === "b100".U && !func(0)
328    def logicToLsb(func: UInt) = Cat("b110".U(3.W), func(3, 1), 0.U(1.W))
329    def logicToZexth(func: UInt) = Cat("b110".U(3.W), func(3, 1), 1.U(1.W))
330    def isBranch(func: UInt) = func(6, 4) === "b111".U
331    def getBranchType(func: UInt) = func(3, 2)
332    def isBranchInvert(func: UInt) = func(1)
333
334    def apply() = UInt(7.W)
335  }
336
337  object MDUOpType {
338    // mul
339    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
340    def mul    = "b00000".U
341    def mulh   = "b00001".U
342    def mulhsu = "b00010".U
343    def mulhu  = "b00011".U
344    def mulw   = "b00100".U
345
346    def mulw7  = "b01100".U
347
348    // div
349    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
350    def div    = "b10000".U
351    def divu   = "b10010".U
352    def rem    = "b10001".U
353    def remu   = "b10011".U
354
355    def divw   = "b10100".U
356    def divuw  = "b10110".U
357    def remw   = "b10101".U
358    def remuw  = "b10111".U
359
360    def isMul(op: UInt) = !op(4)
361    def isDiv(op: UInt) = op(4)
362
363    def isDivSign(op: UInt) = isDiv(op) && !op(1)
364    def isW(op: UInt) = op(2)
365    def isH(op: UInt) = (isDiv(op) && op(0)) || (isMul(op) && op(1, 0) =/= 0.U)
366    def getMulOp(op: UInt) = op(1, 0)
367  }
368
369  object LSUOpType {
370    // load pipeline
371
372    // normal load
373    // Note: bit(1, 0) are size, DO NOT CHANGE
374    // bit encoding: | load 0 | is unsigned(1bit) | size(2bit) |
375    def lb       = "b0000".U
376    def lh       = "b0001".U
377    def lw       = "b0010".U
378    def ld       = "b0011".U
379    def lbu      = "b0100".U
380    def lhu      = "b0101".U
381    def lwu      = "b0110".U
382    // hypervior load
383    // bit encoding: | hlvx 1 | hlv 1 | load 0 | is unsigned(1bit) | size(2bit) |
384    def hlvb = "b10000".U
385    def hlvh = "b10001".U
386    def hlvw = "b10010".U
387    def hlvd = "b10011".U
388    def hlvbu = "b10100".U
389    def hlvhu = "b10101".U
390    def hlvwu = "b10110".U
391    def hlvxhu = "b110101".U
392    def hlvxwu = "b110110".U
393    def isHlv(op: UInt): Bool = op(4)
394    def isHlvx(op: UInt): Bool = op(5)
395
396    // Zicbop software prefetch
397    // bit encoding: | prefetch 1 | 0 | prefetch type (2bit) |
398    def prefetch_i = "b1000".U // TODO
399    def prefetch_r = "b1001".U
400    def prefetch_w = "b1010".U
401
402    def isPrefetch(op: UInt): Bool = op(3)
403
404    // store pipeline
405    // normal store
406    // bit encoding: | store 00 | size(2bit) |
407    def sb       = "b0000".U
408    def sh       = "b0001".U
409    def sw       = "b0010".U
410    def sd       = "b0011".U
411
412    //hypervisor store
413    // bit encoding: |hsv 1 | store 00 | size(2bit) |
414    def hsvb = "b10000".U
415    def hsvh = "b10001".U
416    def hsvw = "b10010".U
417    def hsvd = "b10011".U
418    def isHsv(op: UInt): Bool = op(4)
419
420    // l1 cache op
421    // bit encoding: | cbo_zero 01 | size(2bit) 11 |
422    def cbo_zero  = "b0111".U
423
424    // llc op
425    // bit encoding: | prefetch 11 | suboptype(2bit) |
426    def cbo_clean = "b1100".U
427    def cbo_flush = "b1101".U
428    def cbo_inval = "b1110".U
429
430    def isCbo(op: UInt): Bool = op(3, 2) === "b11".U
431
432    // atomics
433    // bit(1, 0) are size
434    // since atomics use a different fu type
435    // so we can safely reuse other load/store's encodings
436    // bit encoding: | optype(4bit) | size (2bit) |
437    def lr_w      = "b000010".U
438    def sc_w      = "b000110".U
439    def amoswap_w = "b001010".U
440    def amoadd_w  = "b001110".U
441    def amoxor_w  = "b010010".U
442    def amoand_w  = "b010110".U
443    def amoor_w   = "b011010".U
444    def amomin_w  = "b011110".U
445    def amomax_w  = "b100010".U
446    def amominu_w = "b100110".U
447    def amomaxu_w = "b101010".U
448
449    def lr_d      = "b000011".U
450    def sc_d      = "b000111".U
451    def amoswap_d = "b001011".U
452    def amoadd_d  = "b001111".U
453    def amoxor_d  = "b010011".U
454    def amoand_d  = "b010111".U
455    def amoor_d   = "b011011".U
456    def amomin_d  = "b011111".U
457    def amomax_d  = "b100011".U
458    def amominu_d = "b100111".U
459    def amomaxu_d = "b101011".U
460
461    def size(op: UInt) = op(1,0)
462  }
463
464  object BKUOpType {
465
466    def clmul       = "b000000".U
467    def clmulh      = "b000001".U
468    def clmulr      = "b000010".U
469    def xpermn      = "b000100".U
470    def xpermb      = "b000101".U
471
472    def clz         = "b001000".U
473    def clzw        = "b001001".U
474    def ctz         = "b001010".U
475    def ctzw        = "b001011".U
476    def cpop        = "b001100".U
477    def cpopw       = "b001101".U
478
479    // 01xxxx is reserve
480    def aes64es     = "b100000".U
481    def aes64esm    = "b100001".U
482    def aes64ds     = "b100010".U
483    def aes64dsm    = "b100011".U
484    def aes64im     = "b100100".U
485    def aes64ks1i   = "b100101".U
486    def aes64ks2    = "b100110".U
487
488    // merge to two instruction sm4ks & sm4ed
489    def sm4ed0      = "b101000".U
490    def sm4ed1      = "b101001".U
491    def sm4ed2      = "b101010".U
492    def sm4ed3      = "b101011".U
493    def sm4ks0      = "b101100".U
494    def sm4ks1      = "b101101".U
495    def sm4ks2      = "b101110".U
496    def sm4ks3      = "b101111".U
497
498    def sha256sum0  = "b110000".U
499    def sha256sum1  = "b110001".U
500    def sha256sig0  = "b110010".U
501    def sha256sig1  = "b110011".U
502    def sha512sum0  = "b110100".U
503    def sha512sum1  = "b110101".U
504    def sha512sig0  = "b110110".U
505    def sha512sig1  = "b110111".U
506
507    def sm3p0       = "b111000".U
508    def sm3p1       = "b111001".U
509  }
510
511  object BTBtype {
512    def B = "b00".U  // branch
513    def J = "b01".U  // jump
514    def I = "b10".U  // indirect
515    def R = "b11".U  // return
516
517    def apply() = UInt(2.W)
518  }
519
520  object SelImm {
521    def IMM_X  = "b0111".U
522    def IMM_S  = "b0000".U
523    def IMM_SB = "b0001".U
524    def IMM_U  = "b0010".U
525    def IMM_UJ = "b0011".U
526    def IMM_I  = "b0100".U
527    def IMM_Z  = "b0101".U
528    def INVALID_INSTR = "b0110".U
529    def IMM_B6 = "b1000".U
530
531    def X      = BitPat("b????")
532
533    def apply() = UInt(4.W)
534  }
535
536  object ExceptionNO {
537    def instrAddrMisaligned = 0
538    def instrAccessFault    = 1
539    def illegalInstr        = 2
540    def breakPoint          = 3
541    def loadAddrMisaligned  = 4
542    def loadAccessFault     = 5
543    def storeAddrMisaligned = 6
544    def storeAccessFault    = 7
545    def ecallU              = 8
546    def ecallS              = 9
547    def ecallVS             = 10
548    def ecallM              = 11
549    def instrPageFault      = 12
550    def loadPageFault       = 13
551    // def singleStep          = 14
552    def storePageFault      = 15
553    def instrGuestPageFault = 20
554    def loadGuestPageFault  = 21
555    def virtualInstr        = 22
556    def storeGuestPageFault = 23
557    def priorities = Seq(
558      breakPoint, // TODO: different BP has different priority
559      instrPageFault,
560      instrGuestPageFault,
561      instrAccessFault,
562      illegalInstr,
563      virtualInstr,
564      instrAddrMisaligned,
565      ecallM, ecallS, ecallVS, ecallU,
566      storeAddrMisaligned,
567      loadAddrMisaligned,
568      storePageFault,
569      loadPageFault,
570      storeGuestPageFault,
571      loadGuestPageFault,
572      storeAccessFault,
573      loadAccessFault
574    )
575    def all = priorities.distinct.sorted
576    def frontendSet = Seq(
577      instrAddrMisaligned,
578      instrAccessFault,
579      illegalInstr,
580      instrPageFault,
581      instrGuestPageFault,
582      virtualInstr
583    )
584    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
585      val new_vec = Wire(ExceptionVec())
586      new_vec.foreach(_ := false.B)
587      select.foreach(i => new_vec(i) := vec(i))
588      new_vec
589    }
590    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
591    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
592    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
593      partialSelect(vec, fuConfig.exceptionOut)
594    def selectByExu(vec:Vec[Bool], exuConfig: ExuConfig): Vec[Bool] =
595      partialSelect(vec, exuConfig.exceptionOut)
596    def selectByExu(vec:Vec[Bool], exuConfigs: Seq[ExuConfig]): Vec[Bool] =
597      partialSelect(vec, exuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted)
598  }
599
600  def dividerGen(p: Parameters) = new DividerWrapper(p(XLen))(p)
601  def multiplierGen(p: Parameters) = new ArrayMultiplier(p(XLen) + 1)(p)
602  def aluGen(p: Parameters) = new Alu()(p)
603  def bkuGen(p: Parameters) = new Bku()(p)
604  def jmpGen(p: Parameters) = new Jump()(p)
605  def fenceGen(p: Parameters) = new Fence()(p)
606  def csrGen(p: Parameters) = new CSR()(p)
607  def i2fGen(p: Parameters) = new IntToFP()(p)
608  def fmacGen(p: Parameters) = new FMA()(p)
609  def f2iGen(p: Parameters) = new FPToInt()(p)
610  def f2fGen(p: Parameters) = new FPToFP()(p)
611  def fdivSqrtGen(p: Parameters) = new FDivSqrt()(p)
612  def stdGen(p: Parameters) = new Std()(p)
613  def mouDataGen(p: Parameters) = new Std()(p)
614
615  def f2iSel(uop: MicroOp): Bool = {
616    uop.ctrl.rfWen
617  }
618
619  def i2fSel(uop: MicroOp): Bool = {
620    uop.ctrl.fpu.fromInt
621  }
622
623  def f2fSel(uop: MicroOp): Bool = {
624    val ctrl = uop.ctrl.fpu
625    ctrl.fpWen && !ctrl.div && !ctrl.sqrt
626  }
627
628  def fdivSqrtSel(uop: MicroOp): Bool = {
629    val ctrl = uop.ctrl.fpu
630    ctrl.div || ctrl.sqrt
631  }
632
633  val aluCfg = FuConfig(
634    name = "alu",
635    fuGen = aluGen,
636    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.alu,
637    fuType = FuType.alu,
638    numIntSrc = 2,
639    numFpSrc = 0,
640    writeIntRf = true,
641    writeFpRf = false,
642    hasRedirect = true,
643  )
644
645  val jmpCfg = FuConfig(
646    name = "jmp",
647    fuGen = jmpGen,
648    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.jmp,
649    fuType = FuType.jmp,
650    numIntSrc = 1,
651    numFpSrc = 0,
652    writeIntRf = true,
653    writeFpRf = false,
654    hasRedirect = true,
655  )
656
657  val fenceCfg = FuConfig(
658    name = "fence",
659    fuGen = fenceGen,
660    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.fence,
661    FuType.fence, 2, 0, writeIntRf = false, writeFpRf = false,
662    latency = UncertainLatency(), exceptionOut = Seq(illegalInstr, virtualInstr), // TODO: need rewrite latency structure, not just this value,
663    flushPipe = true
664  )
665
666  val csrCfg = FuConfig(
667    name = "csr",
668    fuGen = csrGen,
669    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.csr,
670    fuType = FuType.csr,
671    numIntSrc = 1,
672    numFpSrc = 0,
673    writeIntRf = true,
674    writeFpRf = false,
675    exceptionOut = Seq(illegalInstr, virtualInstr, breakPoint, ecallU, ecallS, ecallVS, ecallM),
676    flushPipe = true
677  )
678
679  val i2fCfg = FuConfig(
680    name = "i2f",
681    fuGen = i2fGen,
682    fuSel = i2fSel,
683    FuType.i2f,
684    numIntSrc = 1,
685    numFpSrc = 0,
686    writeIntRf = false,
687    writeFpRf = true,
688    writeFflags = true,
689    latency = CertainLatency(2),
690    fastUopOut = true, fastImplemented = true
691  )
692
693  val divCfg = FuConfig(
694    name = "div",
695    fuGen = dividerGen,
696    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.div,
697    FuType.div,
698    2,
699    0,
700    writeIntRf = true,
701    writeFpRf = false,
702    latency = UncertainLatency(),
703    fastUopOut = true,
704    fastImplemented = true,
705    hasInputBuffer = (true, 4, true)
706  )
707
708  val mulCfg = FuConfig(
709    name = "mul",
710    fuGen = multiplierGen,
711    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.mul,
712    FuType.mul,
713    2,
714    0,
715    writeIntRf = true,
716    writeFpRf = false,
717    latency = CertainLatency(2),
718    fastUopOut = true,
719    fastImplemented = true
720  )
721
722  val bkuCfg = FuConfig(
723    name = "bku",
724    fuGen = bkuGen,
725    fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.bku,
726    fuType = FuType.bku,
727    numIntSrc = 2,
728    numFpSrc = 0,
729    writeIntRf = true,
730    writeFpRf = false,
731    latency = CertainLatency(1),
732    fastUopOut = true,
733    fastImplemented = true
734 )
735
736  val fmacCfg = FuConfig(
737    name = "fmac",
738    fuGen = fmacGen,
739    fuSel = _ => true.B,
740    FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, writeFflags = true,
741    latency = UncertainLatency(), fastUopOut = true, fastImplemented = true
742  )
743
744  val f2iCfg = FuConfig(
745    name = "f2i",
746    fuGen = f2iGen,
747    fuSel = f2iSel,
748    FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, writeFflags = true, latency = CertainLatency(2),
749    fastUopOut = true, fastImplemented = true
750  )
751
752  val f2fCfg = FuConfig(
753    name = "f2f",
754    fuGen = f2fGen,
755    fuSel = f2fSel,
756    FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = CertainLatency(2),
757    fastUopOut = true, fastImplemented = true
758  )
759
760  val fdivSqrtCfg = FuConfig(
761    name = "fdivSqrt",
762    fuGen = fdivSqrtGen,
763    fuSel = fdivSqrtSel,
764    FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = UncertainLatency(),
765    fastUopOut = true, fastImplemented = true, hasInputBuffer = (true, 8, true)
766  )
767
768  val lduCfg = FuConfig(
769    "ldu",
770    null, // DontCare
771    (uop: MicroOp) => FuType.loadCanAccept(uop.ctrl.fuType),
772    FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true,
773    latency = UncertainLatency(),
774    exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault),
775    flushPipe = true,
776    replayInst = true,
777    hasLoadError = true
778  )
779
780  val staCfg = FuConfig(
781    "sta",
782    null,
783    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
784    FuType.stu, 1, 0, writeIntRf = false, writeFpRf = false,
785    latency = UncertainLatency(),
786    exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault)
787  )
788
789  val stdCfg = FuConfig(
790    "std",
791    fuGen = stdGen, fuSel = (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), FuType.stu, 1, 1,
792    writeIntRf = false, writeFpRf = false, latency = CertainLatency(1)
793  )
794
795  val mouCfg = FuConfig(
796    "mou",
797    null,
798    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
799    FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false,
800    latency = UncertainLatency(), exceptionOut = lduCfg.exceptionOut ++ staCfg.exceptionOut
801  )
802
803  val mouDataCfg = FuConfig(
804    "mou",
805    mouDataGen,
806    (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType),
807    FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false,
808    latency = UncertainLatency()
809  )
810
811  val JumpExeUnitCfg = ExuConfig("JmpExeUnit", "Int", Seq(jmpCfg, i2fCfg), 2, Int.MaxValue)
812  val AluExeUnitCfg = ExuConfig("AluExeUnit", "Int", Seq(aluCfg), 0, Int.MaxValue)
813  val JumpCSRExeUnitCfg = ExuConfig("JmpCSRExeUnit", "Int", Seq(jmpCfg, csrCfg, fenceCfg, i2fCfg), 2, Int.MaxValue)
814  val MulDivExeUnitCfg = ExuConfig("MulDivExeUnit", "Int", Seq(mulCfg, divCfg, bkuCfg), 1, Int.MaxValue)
815  val FmacExeUnitCfg = ExuConfig("FmacExeUnit", "Fp", Seq(fmacCfg), Int.MaxValue, 0)
816  val FmiscExeUnitCfg = ExuConfig(
817    "FmiscExeUnit",
818    "Fp",
819    Seq(f2iCfg, f2fCfg, fdivSqrtCfg),
820    Int.MaxValue, 1
821  )
822  val LdExeUnitCfg = ExuConfig("LoadExu", "Mem", Seq(lduCfg.copy(exceptionOut = mouCfg.exceptionOut)), wbIntPriority = 0, wbFpPriority = 0, extendsExu = false)
823  val StaExeUnitCfg = ExuConfig("StaExu", "Mem", Seq(staCfg, mouCfg.copy(exceptionOut = Seq())), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false)
824  val StdExeUnitCfg = ExuConfig("StdExu", "Mem", Seq(stdCfg, mouDataCfg), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false)
825
826  object TopDownCounters extends Enumeration {
827    val NoStall = Value("NoStall")  // Base
828    // frontend
829    val OverrideBubble = Value("OverrideBubble")
830    val FtqUpdateBubble = Value("FtqUpdateBubble")
831    // val ControlRedirectBubble = Value("ControlRedirectBubble")
832    val TAGEMissBubble = Value("TAGEMissBubble")
833    val SCMissBubble = Value("SCMissBubble")
834    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
835    val RASMissBubble = Value("RASMissBubble")
836    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
837    val OtherRedirectBubble = Value("OtherRedirectBubble")
838    val FtqFullStall = Value("FtqFullStall")
839
840    val ICacheMissBubble = Value("ICacheMissBubble")
841    val ITLBMissBubble = Value("ITLBMissBubble")
842    val BTBMissBubble = Value("BTBMissBubble")
843    val FetchFragBubble = Value("FetchFragBubble")
844
845    // backend
846    // long inst stall at rob head
847    val DivStall = Value("DivStall") // int div, float div/sqrt
848    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
849    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
850    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
851    // freelist full
852    val IntFlStall = Value("IntFlStall")
853    val FpFlStall = Value("FpFlStall")
854    // dispatch queue full
855    val IntDqStall = Value("IntDqStall")
856    val FpDqStall = Value("FpDqStall")
857    val LsDqStall = Value("LsDqStall")
858
859    // memblock
860    val LoadTLBStall = Value("LoadTLBStall")
861    val LoadL1Stall = Value("LoadL1Stall")
862    val LoadL2Stall = Value("LoadL2Stall")
863    val LoadL3Stall = Value("LoadL3Stall")
864    val LoadMemStall = Value("LoadMemStall")
865    val StoreStall = Value("StoreStall") // include store tlb miss
866    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
867
868    // xs replay (different to gem5)
869    val LoadVioReplayStall = Value("LoadVioReplayStall")
870    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
871
872    // bad speculation
873    val ControlRecoveryStall = Value("ControlRecoveryStall")
874    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
875    val OtherRecoveryStall = Value("OtherRecoveryStall")
876
877    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
878
879    val OtherCoreStall = Value("OtherCoreStall")
880
881    val NumStallReasons = Value("NumStallReasons")
882  }
883}
884