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