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