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