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