xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision f7063a43ab34da917ba6c670d21871314340c550)
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.fu.vector._
25import xiangshan.backend.issue._
26import xiangshan.backend.fu.FuConfig
27import xiangshan.backend.decode.{Imm, ImmUnion}
28
29package object xiangshan {
30  object SrcType {
31    def imm = "b000".U
32    def pc  = "b000".U
33    def xp  = "b001".U
34    def fp  = "b010".U
35    def vp  = "b100".U
36    def no  = "b000".U // this src read no reg but cannot be Any value
37
38    // alias
39    def reg = this.xp
40    def DC  = imm // Don't Care
41    def X   = BitPat("b000")
42
43    def isPc(srcType: UInt) = srcType===pc
44    def isImm(srcType: UInt) = srcType===imm
45    def isReg(srcType: UInt) = srcType(0)
46    def isXp(srcType: UInt) = srcType(0)
47    def isFp(srcType: UInt) = srcType(1)
48    def isVp(srcType: UInt) = srcType(2)
49    def isPcOrImm(srcType: UInt) = isPc(srcType) || isImm(srcType)
50    def isNotReg(srcType: UInt): Bool = !srcType.orR
51    def isVfp(srcType: UInt) = isVp(srcType) || isFp(srcType)
52    def apply() = UInt(3.W)
53  }
54
55  object SrcState {
56    def busy    = "b0".U
57    def rdy     = "b1".U
58    // def specRdy = "b10".U // speculative ready, for future use
59    def apply() = UInt(1.W)
60
61    def isReady(state: UInt): Bool = state === this.rdy
62    def isBusy(state: UInt): Bool = state === this.busy
63  }
64
65  def FuOpTypeWidth = 9
66  object FuOpType {
67    def apply() = UInt(FuOpTypeWidth.W)
68    def X     = BitPat("b0_0000_0000")
69    def FMVXF = BitPat("b1_1000_0000") //for fmv_x_d & fmv_x_w
70  }
71
72  object VlduType {
73    // bit encoding: | padding (2bit) || mop (2bit) | lumop(5bit) |
74    // only unit-stride use lumop
75    // mop [1:0]
76    // 0 0 : unit-stride
77    // 0 1 : indexed-unordered
78    // 1 0 : strided
79    // 1 1 : indexed-ordered
80    // lumop[4:0]
81    // 0 0 0 0 0 : unit-stride load
82    // 0 1 0 0 0 : unit-stride, whole register load
83    // 0 1 0 1 1 : unit-stride, mask load, EEW=8
84    // 1 0 0 0 0 : unit-stride fault-only-first
85    def vle       = "b00_00_00000".U
86    def vlr       = "b00_00_01000".U
87    def vlm       = "b00_00_01011".U
88    def vleff     = "b00_00_10000".U
89    def vluxe     = "b00_01_00000".U
90    def vlse      = "b00_10_00000".U
91    def vloxe     = "b00_11_00000".U
92
93    def isStrided(fuOpType: UInt): Bool = fuOpType === vlse
94    def isIndexed(fuOpType: UInt): Bool = fuOpType === vluxe || fuOpType === vloxe
95    def isMasked(fuOpType: UInt): Bool = fuOpType === vlm
96  }
97
98  object VstuType {
99    // bit encoding: | padding (2bit) || mop (2bit) | sumop(5bit) |
100    // only unit-stride use sumop
101    // mop [1:0]
102    // 0 0 : unit-stride
103    // 0 1 : indexed-unordered
104    // 1 0 : strided
105    // 1 1 : indexed-ordered
106    // sumop[4:0]
107    // 0 0 0 0 0 : unit-stride load
108    // 0 1 0 0 0 : unit-stride, whole register load
109    // 0 1 0 1 1 : unit-stride, mask load, EEW=8
110    def vse       = "b00_00_00000".U
111    def vsr       = "b00_00_01000".U
112    def vsm       = "b00_00_01011".U
113    def vsuxe     = "b00_01_00000".U
114    def vsse      = "b00_10_00000".U
115    def vsoxe     = "b00_11_00000".U
116
117    def isStrided(fuOpType: UInt): Bool = fuOpType === vsse
118    def isIndexed(fuOpType: UInt): Bool = fuOpType === vsuxe || fuOpType === vsoxe
119  }
120
121  object IF2VectorType {
122    // use last 2 bits for vsew
123    def iDup2Vec   = "b1_00".U
124    def fDup2Vec   = "b1_00".U
125    def immDup2Vec = "b1_10".U
126    def i2Vec      = "b0_00".U
127    def f2Vec      = "b0_01".U
128    def imm2Vec    = "b0_10".U
129    def needDup(bits: UInt): Bool = bits(2)
130    def isImm(bits: UInt): Bool = bits(1)
131    def isFmv(bits: UInt): Bool = bits(0)
132    def FMX_D_X    = "b0_01_11".U
133    def FMX_W_X    = "b0_01_10".U
134  }
135
136  object CommitType {
137    def NORMAL = "b000".U  // int/fp
138    def BRANCH = "b001".U  // branch
139    def LOAD   = "b010".U  // load
140    def STORE  = "b011".U  // store
141
142    def apply() = UInt(3.W)
143    def isFused(commitType: UInt): Bool = commitType(2)
144    def isLoadStore(commitType: UInt): Bool = !isFused(commitType) && commitType(1)
145    def lsInstIsStore(commitType: UInt): Bool = commitType(0)
146    def isStore(commitType: UInt): Bool = isLoadStore(commitType) && lsInstIsStore(commitType)
147    def isBranch(commitType: UInt): Bool = commitType(0) && !commitType(1) && !isFused(commitType)
148  }
149
150  object RedirectLevel {
151    def flushAfter = "b0".U
152    def flush      = "b1".U
153
154    def apply() = UInt(1.W)
155    // def isUnconditional(level: UInt) = level(1)
156    def flushItself(level: UInt) = level(0)
157    // def isException(level: UInt) = level(1) && level(0)
158  }
159
160  object ExceptionVec {
161    val ExceptionVecSize = 24
162    def apply() = Vec(ExceptionVecSize, Bool())
163  }
164
165  object PMAMode {
166    def R = "b1".U << 0 //readable
167    def W = "b1".U << 1 //writeable
168    def X = "b1".U << 2 //executable
169    def I = "b1".U << 3 //cacheable: icache
170    def D = "b1".U << 4 //cacheable: dcache
171    def S = "b1".U << 5 //enable speculative access
172    def A = "b1".U << 6 //enable atomic operation, A imply R & W
173    def C = "b1".U << 7 //if it is cacheable is configable
174    def Reserved = "b0".U
175
176    def apply() = UInt(7.W)
177
178    def read(mode: UInt) = mode(0)
179    def write(mode: UInt) = mode(1)
180    def execute(mode: UInt) = mode(2)
181    def icache(mode: UInt) = mode(3)
182    def dcache(mode: UInt) = mode(4)
183    def speculate(mode: UInt) = mode(5)
184    def atomic(mode: UInt) = mode(6)
185    def configable_cache(mode: UInt) = mode(7)
186
187    def strToMode(s: String) = {
188      var result = 0.U(8.W)
189      if (s.toUpperCase.indexOf("R") >= 0) result = result + R
190      if (s.toUpperCase.indexOf("W") >= 0) result = result + W
191      if (s.toUpperCase.indexOf("X") >= 0) result = result + X
192      if (s.toUpperCase.indexOf("I") >= 0) result = result + I
193      if (s.toUpperCase.indexOf("D") >= 0) result = result + D
194      if (s.toUpperCase.indexOf("S") >= 0) result = result + S
195      if (s.toUpperCase.indexOf("A") >= 0) result = result + A
196      if (s.toUpperCase.indexOf("C") >= 0) result = result + C
197      result
198    }
199  }
200
201
202  object CSROpType {
203    def jmp  = "b000".U
204    def wrt  = "b001".U
205    def set  = "b010".U
206    def clr  = "b011".U
207    def wfi  = "b100".U
208    def wrti = "b101".U
209    def seti = "b110".U
210    def clri = "b111".U
211    def needAccess(op: UInt): Bool = op(1, 0) =/= 0.U
212  }
213
214  // jump
215  object JumpOpType {
216    def jal  = "b00".U
217    def jalr = "b01".U
218    def auipc = "b10".U
219//    def call = "b11_011".U
220//    def ret  = "b11_100".U
221    def jumpOpisJalr(op: UInt) = op(0)
222    def jumpOpisAuipc(op: UInt) = op(1)
223  }
224
225  object FenceOpType {
226    def fence  = "b10000".U
227    def sfence = "b10001".U
228    def fencei = "b10010".U
229    def hfence_v = "b10011".U
230    def hfence_g = "b10100".U
231    def nofence= "b00000".U
232  }
233
234  object ALUOpType {
235    // shift optype
236    def slliuw     = "b000_0000".U // slliuw: ZEXT(src1[31:0]) << shamt
237    def sll        = "b000_0001".U // sll:     src1 << src2
238
239    def bclr       = "b000_0010".U // bclr:    src1 & ~(1 << src2[5:0])
240    def bset       = "b000_0011".U // bset:    src1 | (1 << src2[5:0])
241    def binv       = "b000_0100".U // binv:    src1 ^ ~(1 << src2[5:0])
242
243    def srl        = "b000_0101".U // srl:     src1 >> src2
244    def bext       = "b000_0110".U // bext:    (src1 >> src2)[0]
245    def sra        = "b000_0111".U // sra:     src1 >> src2 (arithmetic)
246
247    def rol        = "b000_1001".U // rol:     (src1 << src2) | (src1 >> (xlen - src2))
248    def ror        = "b000_1011".U // ror:     (src1 >> src2) | (src1 << (xlen - src2))
249
250    // RV64 32bit optype
251    def addw       = "b001_0000".U // addw:      SEXT((src1 + src2)[31:0])
252    def oddaddw    = "b001_0001".U // oddaddw:   SEXT((src1[0] + src2)[31:0])
253    def subw       = "b001_0010".U // subw:      SEXT((src1 - src2)[31:0])
254    def lui32addw  = "b001_0011".U // lui32addw: SEXT(SEXT(src2[11:0], 32) + {src2[31:12], 12'b0}, 64)
255
256    def addwbit    = "b001_0100".U // addwbit:   (src1 + src2)[0]
257    def addwbyte   = "b001_0101".U // addwbyte:  (src1 + src2)[7:0]
258    def addwzexth  = "b001_0110".U // addwzexth: ZEXT((src1  + src2)[15:0])
259    def addwsexth  = "b001_0111".U // addwsexth: SEXT((src1  + src2)[15:0])
260
261    def sllw       = "b001_1000".U // sllw:     SEXT((src1 << src2)[31:0])
262    def srlw       = "b001_1001".U // srlw:     SEXT((src1[31:0] >> src2)[31:0])
263    def sraw       = "b001_1010".U // sraw:     SEXT((src1[31:0] >> src2)[31:0])
264    def rolw       = "b001_1100".U
265    def rorw       = "b001_1101".U
266
267    // ADD-op
268    def adduw      = "b010_0000".U // adduw:  src1[31:0]  + src2
269    def add        = "b010_0001".U // add:     src1        + src2
270    def oddadd     = "b010_0010".U // oddadd:  src1[0]     + src2
271    def lui32add   = "b010_0011".U // lui32add: SEXT(src2[11:0]) + {src2[63:12], 12'b0}
272
273    def sr29add    = "b010_0100".U // sr29add: src1[63:29] + src2
274    def sr30add    = "b010_0101".U // sr30add: src1[63:30] + src2
275    def sr31add    = "b010_0110".U // sr31add: src1[63:31] + src2
276    def sr32add    = "b010_0111".U // sr32add: src1[63:32] + src2
277
278    def sh1adduw   = "b010_1000".U // sh1adduw: {src1[31:0], 1'b0} + src2
279    def sh1add     = "b010_1001".U // sh1add: {src1[62:0], 1'b0} + src2
280    def sh2adduw   = "b010_1010".U // sh2add_uw: {src1[31:0], 2'b0} + src2
281    def sh2add     = "b010_1011".U // sh2add: {src1[61:0], 2'b0} + src2
282    def sh3adduw   = "b010_1100".U // sh3add_uw: {src1[31:0], 3'b0} + src2
283    def sh3add     = "b010_1101".U // sh3add: {src1[60:0], 3'b0} + src2
284    def sh4add     = "b010_1111".U // sh4add: {src1[59:0], 4'b0} + src2
285
286    // SUB-op: src1 - src2
287    def sub        = "b011_0000".U
288    def sltu       = "b011_0001".U
289    def slt        = "b011_0010".U
290    def maxu       = "b011_0100".U
291    def minu       = "b011_0101".U
292    def max        = "b011_0110".U
293    def min        = "b011_0111".U
294
295    // branch
296    def beq        = "b111_0000".U
297    def bne        = "b111_0010".U
298    def blt        = "b111_1000".U
299    def bge        = "b111_1010".U
300    def bltu       = "b111_1100".U
301    def bgeu       = "b111_1110".U
302
303    // misc optype
304    def and        = "b100_0000".U
305    def andn       = "b100_0001".U
306    def or         = "b100_0010".U
307    def orn        = "b100_0011".U
308    def xor        = "b100_0100".U
309    def xnor       = "b100_0101".U
310    def orcb       = "b100_0110".U
311
312    def sextb      = "b100_1000".U
313    def packh      = "b100_1001".U
314    def sexth      = "b100_1010".U
315    def packw      = "b100_1011".U
316
317    def revb       = "b101_0000".U
318    def rev8       = "b101_0001".U
319    def pack       = "b101_0010".U
320    def orh48      = "b101_0011".U
321
322    def szewl1     = "b101_1000".U
323    def szewl2     = "b101_1001".U
324    def szewl3     = "b101_1010".U
325    def byte2      = "b101_1011".U
326
327    def andlsb     = "b110_0000".U
328    def andzexth   = "b110_0001".U
329    def orlsb      = "b110_0010".U
330    def orzexth    = "b110_0011".U
331    def xorlsb     = "b110_0100".U
332    def xorzexth   = "b110_0101".U
333    def orcblsb    = "b110_0110".U
334    def orcbzexth  = "b110_0111".U
335
336    def isAddw(func: UInt) = func(6, 4) === "b001".U && !func(3) && !func(1)
337    def isSimpleLogic(func: UInt) = func(6, 4) === "b100".U && !func(0)
338    def logicToLsb(func: UInt) = Cat("b110".U(3.W), func(3, 1), 0.U(1.W))
339    def logicToZexth(func: UInt) = Cat("b110".U(3.W), func(3, 1), 1.U(1.W))
340
341    def apply() = UInt(FuOpTypeWidth.W)
342  }
343
344  object VSETOpType {
345    val setVlmaxBit = 0
346    val keepVlBit   = 1
347    // destTypeBit == 0: write vl to rd
348    // destTypeBit == 1: write vconfig
349    val destTypeBit = 5
350
351    // vsetvli's uop
352    //   rs1!=x0, normal
353    //     uop0: r(rs1), w(vconfig)     | x[rs1],vtypei  -> vconfig
354    //     uop1: r(rs1), w(rd)          | x[rs1],vtypei  -> x[rd]
355    def uvsetvcfg_xi        = "b1010_0000".U
356    def uvsetrd_xi          = "b1000_0000".U
357    //   rs1==x0, rd!=x0, set vl to vlmax, set rd to vlmax, set vtype
358    //     uop0: w(vconfig)             | vlmax, vtypei  -> vconfig
359    //     uop1: w(rd)                  | vlmax, vtypei  -> x[rd]
360    def uvsetvcfg_vlmax_i   = "b1010_0001".U
361    def uvsetrd_vlmax_i     = "b1000_0001".U
362    //   rs1==x0, rd==x0, keep vl, set vtype
363    //     uop0: r(vconfig), w(vconfig) | ld_vconfig.vl, vtypei -> vconfig
364    def uvsetvcfg_keep_v    = "b1010_0010".U
365
366    // vsetvl's uop
367    //   rs1!=x0, normal
368    //     uop0: r(rs1,rs2), w(vconfig) | x[rs1],x[rs2]  -> vconfig
369    //     uop1: r(rs1,rs2), w(rd)      | x[rs1],x[rs2]  -> x[rd]
370    def uvsetvcfg_xx        = "b0110_0000".U
371    def uvsetrd_xx          = "b0100_0000".U
372    //   rs1==x0, rd!=x0, set vl to vlmax, set rd to vlmax, set vtype
373    //     uop0: r(rs2), w(vconfig)     | vlmax, vtypei  -> vconfig
374    //     uop1: r(rs2), w(rd)          | vlmax, vtypei  -> x[rd]
375    def uvsetvcfg_vlmax_x   = "b0110_0001".U
376    def uvsetrd_vlmax_x     = "b0100_0001".U
377    //   rs1==x0, rd==x0, keep vl, set vtype
378    //     uop0: r(rs2), w(vtmp)             | x[rs2]               -> vtmp
379    //     uop0: r(vconfig,vtmp), w(vconfig) | old_vconfig.vl, vtmp -> vconfig
380    def uvmv_v_x            = "b0110_0010".U
381    def uvsetvcfg_vv        = "b0111_0010".U
382
383    // vsetivli's uop
384    //     uop0: w(vconfig)             | vli, vtypei    -> vconfig
385    //     uop1: w(rd)                  | vli, vtypei    -> x[rd]
386    def uvsetvcfg_ii        = "b0010_0000".U
387    def uvsetrd_ii          = "b0000_0000".U
388
389    def isVsetvl  (func: UInt)  = func(6)
390    def isVsetvli (func: UInt)  = func(7)
391    def isVsetivli(func: UInt)  = func(7, 6) === 0.U
392    def isNormal  (func: UInt)  = func(1, 0) === 0.U
393    def isSetVlmax(func: UInt)  = func(setVlmaxBit)
394    def isKeepVl  (func: UInt)  = func(keepVlBit)
395    // RG: region
396    def writeIntRG(func: UInt)  = !func(5)
397    def writeVecRG(func: UInt)  = func(5)
398    def readIntRG (func: UInt)  = !func(4)
399    def readVecRG (func: UInt)  = func(4)
400    // modify fuOpType
401    def keepVl(func: UInt)      = func | (1 << keepVlBit).U
402    def setVlmax(func: UInt)    = func | (1 << setVlmaxBit).U
403  }
404
405  object BRUOpType {
406    // branch
407    def beq        = "b000_000".U
408    def bne        = "b000_001".U
409    def blt        = "b000_100".U
410    def bge        = "b000_101".U
411    def bltu       = "b001_000".U
412    def bgeu       = "b001_001".U
413
414    def getBranchType(func: UInt) = func(3, 1)
415    def isBranchInvert(func: UInt) = func(0)
416  }
417
418  object MULOpType {
419    // mul
420    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
421    def mul    = "b00000".U
422    def mulh   = "b00001".U
423    def mulhsu = "b00010".U
424    def mulhu  = "b00011".U
425    def mulw   = "b00100".U
426
427    def mulw7  = "b01100".U
428    def isSign(op: UInt) = !op(1)
429    def isW(op: UInt) = op(2)
430    def isH(op: UInt) = op(1, 0) =/= 0.U
431    def getOp(op: UInt) = Cat(op(3), op(1, 0))
432  }
433
434  object DIVOpType {
435    // div
436    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
437    def div    = "b10000".U
438    def divu   = "b10010".U
439    def rem    = "b10001".U
440    def remu   = "b10011".U
441
442    def divw   = "b10100".U
443    def divuw  = "b10110".U
444    def remw   = "b10101".U
445    def remuw  = "b10111".U
446
447    def isSign(op: UInt) = !op(1)
448    def isW(op: UInt) = op(2)
449    def isH(op: UInt) = op(0)
450  }
451
452  object MDUOpType {
453    // mul
454    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
455    def mul    = "b00000".U
456    def mulh   = "b00001".U
457    def mulhsu = "b00010".U
458    def mulhu  = "b00011".U
459    def mulw   = "b00100".U
460
461    def mulw7  = "b01100".U
462
463    // div
464    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
465    def div    = "b10000".U
466    def divu   = "b10010".U
467    def rem    = "b10001".U
468    def remu   = "b10011".U
469
470    def divw   = "b10100".U
471    def divuw  = "b10110".U
472    def remw   = "b10101".U
473    def remuw  = "b10111".U
474
475    def isMul(op: UInt) = !op(4)
476    def isDiv(op: UInt) = op(4)
477
478    def isDivSign(op: UInt) = isDiv(op) && !op(1)
479    def isW(op: UInt) = op(2)
480    def isH(op: UInt) = (isDiv(op) && op(0)) || (isMul(op) && op(1, 0) =/= 0.U)
481    def getMulOp(op: UInt) = op(1, 0)
482  }
483
484  object LSUOpType {
485    // load pipeline
486
487    // normal load
488    // Note: bit(1, 0) are size, DO NOT CHANGE
489    // bit encoding: | load 0 | is unsigned(1bit) | size(2bit) |
490    def lb       = "b0000".U
491    def lh       = "b0001".U
492    def lw       = "b0010".U
493    def ld       = "b0011".U
494    def lbu      = "b0100".U
495    def lhu      = "b0101".U
496    def lwu      = "b0110".U
497    // hypervior load
498    // bit encoding: | hlvx 1 | hlv 1 | load 0 | is unsigned(1bit) | size(2bit) |
499    def hlvb = "b10000".U
500    def hlvh = "b10001".U
501    def hlvw = "b10010".U
502    def hlvd = "b10011".U
503    def hlvbu = "b10100".U
504    def hlvhu = "b10101".U
505    def hlvwu = "b10110".U
506    def hlvxhu = "b110101".U
507    def hlvxwu = "b110110".U
508    def isHlv(op: UInt): Bool = op(4)
509    def isHlvx(op: UInt): Bool = op(5)
510
511    // Zicbop software prefetch
512    // bit encoding: | prefetch 1 | 0 | prefetch type (2bit) |
513    def prefetch_i = "b1000".U // TODO
514    def prefetch_r = "b1001".U
515    def prefetch_w = "b1010".U
516
517    def isPrefetch(op: UInt): Bool = op(3)
518
519    // store pipeline
520    // normal store
521    // bit encoding: | store 00 | size(2bit) |
522    def sb       = "b0000".U
523    def sh       = "b0001".U
524    def sw       = "b0010".U
525    def sd       = "b0011".U
526
527    //hypervisor store
528    // bit encoding: |hsv 1 | store 00 | size(2bit) |
529    def hsvb = "b10000".U
530    def hsvh = "b10001".U
531    def hsvw = "b10010".U
532    def hsvd = "b10011".U
533    def isHsv(op: UInt): Bool = op(4)
534
535    // l1 cache op
536    // bit encoding: | cbo_zero 01 | size(2bit) 11 |
537    def cbo_zero  = "b0111".U
538
539    // llc op
540    // bit encoding: | prefetch 11 | suboptype(2bit) |
541    def cbo_clean = "b1100".U
542    def cbo_flush = "b1101".U
543    def cbo_inval = "b1110".U
544
545    def isCbo(op: UInt): Bool = op(3, 2) === "b11".U
546
547    // atomics
548    // bit(1, 0) are size
549    // since atomics use a different fu type
550    // so we can safely reuse other load/store's encodings
551    // bit encoding: | optype(4bit) | size (2bit) |
552    def lr_w      = "b000010".U
553    def sc_w      = "b000110".U
554    def amoswap_w = "b001010".U
555    def amoadd_w  = "b001110".U
556    def amoxor_w  = "b010010".U
557    def amoand_w  = "b010110".U
558    def amoor_w   = "b011010".U
559    def amomin_w  = "b011110".U
560    def amomax_w  = "b100010".U
561    def amominu_w = "b100110".U
562    def amomaxu_w = "b101010".U
563
564    def lr_d      = "b000011".U
565    def sc_d      = "b000111".U
566    def amoswap_d = "b001011".U
567    def amoadd_d  = "b001111".U
568    def amoxor_d  = "b010011".U
569    def amoand_d  = "b010111".U
570    def amoor_d   = "b011011".U
571    def amomin_d  = "b011111".U
572    def amomax_d  = "b100011".U
573    def amominu_d = "b100111".U
574    def amomaxu_d = "b101011".U
575
576    def size(op: UInt) = op(1,0)
577  }
578
579  object BKUOpType {
580
581    def clmul       = "b000000".U
582    def clmulh      = "b000001".U
583    def clmulr      = "b000010".U
584    def xpermn      = "b000100".U
585    def xpermb      = "b000101".U
586
587    def clz         = "b001000".U
588    def clzw        = "b001001".U
589    def ctz         = "b001010".U
590    def ctzw        = "b001011".U
591    def cpop        = "b001100".U
592    def cpopw       = "b001101".U
593
594    // 01xxxx is reserve
595    def aes64es     = "b100000".U
596    def aes64esm    = "b100001".U
597    def aes64ds     = "b100010".U
598    def aes64dsm    = "b100011".U
599    def aes64im     = "b100100".U
600    def aes64ks1i   = "b100101".U
601    def aes64ks2    = "b100110".U
602
603    // merge to two instruction sm4ks & sm4ed
604    def sm4ed0      = "b101000".U
605    def sm4ed1      = "b101001".U
606    def sm4ed2      = "b101010".U
607    def sm4ed3      = "b101011".U
608    def sm4ks0      = "b101100".U
609    def sm4ks1      = "b101101".U
610    def sm4ks2      = "b101110".U
611    def sm4ks3      = "b101111".U
612
613    def sha256sum0  = "b110000".U
614    def sha256sum1  = "b110001".U
615    def sha256sig0  = "b110010".U
616    def sha256sig1  = "b110011".U
617    def sha512sum0  = "b110100".U
618    def sha512sum1  = "b110101".U
619    def sha512sig0  = "b110110".U
620    def sha512sig1  = "b110111".U
621
622    def sm3p0       = "b111000".U
623    def sm3p1       = "b111001".U
624  }
625
626  object BTBtype {
627    def B = "b00".U  // branch
628    def J = "b01".U  // jump
629    def I = "b10".U  // indirect
630    def R = "b11".U  // return
631
632    def apply() = UInt(2.W)
633  }
634
635  object SelImm {
636    def IMM_X  = "b0111".U
637    def IMM_S  = "b1110".U
638    def IMM_SB = "b0001".U
639    def IMM_U  = "b0010".U
640    def IMM_UJ = "b0011".U
641    def IMM_I  = "b0100".U
642    def IMM_Z  = "b0101".U
643    def INVALID_INSTR = "b0110".U
644    def IMM_B6 = "b1000".U
645
646    def IMM_OPIVIS = "b1001".U
647    def IMM_OPIVIU = "b1010".U
648    def IMM_VSETVLI   = "b1100".U
649    def IMM_VSETIVLI  = "b1101".U
650    def IMM_LUI32 = "b1011".U
651    def IMM_VRORVI = "b1111".U
652
653    def X      = BitPat("b0000")
654
655    def apply() = UInt(4.W)
656
657    def mkString(immType: UInt) : String = {
658      val strMap = Map(
659        IMM_S.litValue         -> "S",
660        IMM_SB.litValue        -> "SB",
661        IMM_U.litValue         -> "U",
662        IMM_UJ.litValue        -> "UJ",
663        IMM_I.litValue         -> "I",
664        IMM_Z.litValue         -> "Z",
665        IMM_B6.litValue        -> "B6",
666        IMM_OPIVIS.litValue    -> "VIS",
667        IMM_OPIVIU.litValue    -> "VIU",
668        IMM_VSETVLI.litValue   -> "VSETVLI",
669        IMM_VSETIVLI.litValue  -> "VSETIVLI",
670        IMM_LUI32.litValue     -> "LUI32",
671        IMM_VRORVI.litValue    -> "VRORVI",
672        INVALID_INSTR.litValue -> "INVALID",
673      )
674      strMap(immType.litValue)
675    }
676
677    def getImmUnion(immType: UInt) : Imm = {
678      val iuMap = Map(
679        IMM_S.litValue         -> ImmUnion.S,
680        IMM_SB.litValue        -> ImmUnion.B,
681        IMM_U.litValue         -> ImmUnion.U,
682        IMM_UJ.litValue        -> ImmUnion.J,
683        IMM_I.litValue         -> ImmUnion.I,
684        IMM_Z.litValue         -> ImmUnion.Z,
685        IMM_B6.litValue        -> ImmUnion.B6,
686        IMM_OPIVIS.litValue    -> ImmUnion.OPIVIS,
687        IMM_OPIVIU.litValue    -> ImmUnion.OPIVIU,
688        IMM_VSETVLI.litValue   -> ImmUnion.VSETVLI,
689        IMM_VSETIVLI.litValue  -> ImmUnion.VSETIVLI,
690        IMM_LUI32.litValue     -> ImmUnion.LUI32,
691        IMM_VRORVI.litValue    -> ImmUnion.VRORVI,
692      )
693      iuMap(immType.litValue)
694    }
695  }
696
697  object UopSplitType {
698    def SCA_SIM          = "b000000".U //
699    def VSET             = "b010001".U // dirty: vset
700    def VEC_VVV          = "b010010".U // VEC_VVV
701    def VEC_VXV          = "b010011".U // VEC_VXV
702    def VEC_0XV          = "b010100".U // VEC_0XV
703    def VEC_VVW          = "b010101".U // VEC_VVW
704    def VEC_WVW          = "b010110".U // VEC_WVW
705    def VEC_VXW          = "b010111".U // VEC_VXW
706    def VEC_WXW          = "b011000".U // VEC_WXW
707    def VEC_WVV          = "b011001".U // VEC_WVV
708    def VEC_WXV          = "b011010".U // VEC_WXV
709    def VEC_EXT2         = "b011011".U // VF2 0 -> V
710    def VEC_EXT4         = "b011100".U // VF4 0 -> V
711    def VEC_EXT8         = "b011101".U // VF8 0 -> V
712    def VEC_VVM          = "b011110".U // VEC_VVM
713    def VEC_VXM          = "b011111".U // VEC_VXM
714    def VEC_SLIDE1UP     = "b100000".U // vslide1up.vx
715    def VEC_FSLIDE1UP    = "b100001".U // vfslide1up.vf
716    def VEC_SLIDE1DOWN   = "b100010".U // vslide1down.vx
717    def VEC_FSLIDE1DOWN  = "b100011".U // vfslide1down.vf
718    def VEC_VRED         = "b100100".U // VEC_VRED
719    def VEC_SLIDEUP      = "b100101".U // VEC_SLIDEUP
720    def VEC_SLIDEDOWN    = "b100111".U // VEC_SLIDEDOWN
721    def VEC_M0X          = "b101001".U // VEC_M0X  0MV
722    def VEC_MVV          = "b101010".U // VEC_MVV  VMV
723    def VEC_M0X_VFIRST   = "b101011".U //
724    def VEC_VWW          = "b101100".U //
725    def VEC_RGATHER      = "b101101".U // vrgather.vv, vrgather.vi
726    def VEC_RGATHER_VX   = "b101110".U // vrgather.vx
727    def VEC_RGATHEREI16  = "b101111".U // vrgatherei16.vv
728    def VEC_COMPRESS     = "b110000".U // vcompress.vm
729    def VEC_US_LDST      = "b110001".U // vector unit-strided load/store
730    def VEC_S_LDST       = "b110010".U // vector strided load/store
731    def VEC_I_LDST       = "b110011".U // vector indexed load/store
732    def VEC_VFV          = "b111000".U // VEC_VFV
733    def VEC_VFW          = "b111001".U // VEC_VFW
734    def VEC_WFW          = "b111010".U // VEC_WVW
735    def VEC_VFM          = "b111011".U // VEC_VFM
736    def VEC_VFRED        = "b111100".U // VEC_VFRED
737    def VEC_VFREDOSUM    = "b111101".U // VEC_VFREDOSUM
738    def VEC_M0M          = "b000000".U // VEC_M0M
739    def VEC_MMM          = "b000000".U // VEC_MMM
740    def VEC_MVNR         = "b000100".U // vmvnr
741    def dummy     = "b111111".U
742
743    def X = BitPat("b000000")
744
745    def apply() = UInt(6.W)
746    def needSplit(UopSplitType: UInt) = UopSplitType(4) || UopSplitType(5)
747  }
748
749  object ExceptionNO {
750    def instrAddrMisaligned = 0
751    def instrAccessFault    = 1
752    def illegalInstr        = 2
753    def breakPoint          = 3
754    def loadAddrMisaligned  = 4
755    def loadAccessFault     = 5
756    def storeAddrMisaligned = 6
757    def storeAccessFault    = 7
758    def ecallU              = 8
759    def ecallS              = 9
760    def ecallVS             = 10
761    def ecallM              = 11
762    def instrPageFault      = 12
763    def loadPageFault       = 13
764    // def singleStep          = 14
765    def storePageFault      = 15
766    def instrGuestPageFault = 20
767    def loadGuestPageFault  = 21
768    def virtualInstr        = 22
769    def storeGuestPageFault = 23
770    def priorities = Seq(
771      breakPoint, // TODO: different BP has different priority
772      instrPageFault,
773      instrGuestPageFault,
774      instrAccessFault,
775      illegalInstr,
776      virtualInstr,
777      instrAddrMisaligned,
778      ecallM, ecallS, ecallVS, ecallU,
779      storeAddrMisaligned,
780      loadAddrMisaligned,
781      storePageFault,
782      loadPageFault,
783      storeGuestPageFault,
784      loadGuestPageFault,
785      storeAccessFault,
786      loadAccessFault
787    )
788    def all = priorities.distinct.sorted
789    def frontendSet = Seq(
790      instrAddrMisaligned,
791      instrAccessFault,
792      illegalInstr,
793      instrPageFault,
794      instrGuestPageFault,
795      virtualInstr
796    )
797    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
798      val new_vec = Wire(ExceptionVec())
799      new_vec.foreach(_ := false.B)
800      select.foreach(i => new_vec(i) := vec(i))
801      new_vec
802    }
803    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
804    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
805    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
806      partialSelect(vec, fuConfig.exceptionOut)
807  }
808
809  object TopDownCounters extends Enumeration {
810    val NoStall = Value("NoStall") // Base
811    // frontend
812    val OverrideBubble = Value("OverrideBubble")
813    val FtqUpdateBubble = Value("FtqUpdateBubble")
814    // val ControlRedirectBubble = Value("ControlRedirectBubble")
815    val TAGEMissBubble = Value("TAGEMissBubble")
816    val SCMissBubble = Value("SCMissBubble")
817    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
818    val RASMissBubble = Value("RASMissBubble")
819    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
820    val OtherRedirectBubble = Value("OtherRedirectBubble")
821    val FtqFullStall = Value("FtqFullStall")
822
823    val ICacheMissBubble = Value("ICacheMissBubble")
824    val ITLBMissBubble = Value("ITLBMissBubble")
825    val BTBMissBubble = Value("BTBMissBubble")
826    val FetchFragBubble = Value("FetchFragBubble")
827
828    // backend
829    // long inst stall at rob head
830    val DivStall = Value("DivStall") // int div, float div/sqrt
831    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
832    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
833    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
834    // freelist full
835    val IntFlStall = Value("IntFlStall")
836    val FpFlStall = Value("FpFlStall")
837    // dispatch queue full
838    val IntDqStall = Value("IntDqStall")
839    val FpDqStall = Value("FpDqStall")
840    val LsDqStall = Value("LsDqStall")
841
842    // memblock
843    val LoadTLBStall = Value("LoadTLBStall")
844    val LoadL1Stall = Value("LoadL1Stall")
845    val LoadL2Stall = Value("LoadL2Stall")
846    val LoadL3Stall = Value("LoadL3Stall")
847    val LoadMemStall = Value("LoadMemStall")
848    val StoreStall = Value("StoreStall") // include store tlb miss
849    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
850
851    // xs replay (different to gem5)
852    val LoadVioReplayStall = Value("LoadVioReplayStall")
853    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
854
855    // bad speculation
856    val ControlRecoveryStall = Value("ControlRecoveryStall")
857    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
858    val OtherRecoveryStall = Value("OtherRecoveryStall")
859
860    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
861
862    val OtherCoreStall = Value("OtherCoreStall")
863
864    val NumStallReasons = Value("NumStallReasons")
865  }
866}
867