xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision 12861ac7f75344ad30184de39dc6f646bd48445e)
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 lr_w      = "b000010".U
598    def sc_w      = "b000110".U
599    def amoswap_w = "b001010".U
600    def amoadd_w  = "b001110".U
601    def amoxor_w  = "b010010".U
602    def amoand_w  = "b010110".U
603    def amoor_w   = "b011010".U
604    def amomin_w  = "b011110".U
605    def amomax_w  = "b100010".U
606    def amominu_w = "b100110".U
607    def amomaxu_w = "b101010".U
608    def amocas_w  = "b101110".U
609
610    def lr_d      = "b000011".U
611    def sc_d      = "b000111".U
612    def amoswap_d = "b001011".U
613    def amoadd_d  = "b001111".U
614    def amoxor_d  = "b010011".U
615    def amoand_d  = "b010111".U
616    def amoor_d   = "b011011".U
617    def amomin_d  = "b011111".U
618    def amomax_d  = "b100011".U
619    def amominu_d = "b100111".U
620    def amomaxu_d = "b101011".U
621    def amocas_d  = "b101111".U
622
623    def amocas_q  = "b101100".U
624
625    def isAmocas(op: UInt): Bool = op(5, 2) === "b1011".U
626
627    def size(op: UInt) = op(1,0)
628
629    def getVecLSMop(fuOpType: UInt): UInt = fuOpType(6, 5)
630
631    def isAllUS  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && (fuOpType(8) ^ fuOpType(7))// Unit-Stride Whole Masked
632    def isUStride(fuOpType: UInt): Bool = fuOpType(6, 0) === "b00_00000".U && (fuOpType(8) ^ fuOpType(7))
633    def isWhole  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01000".U && (fuOpType(8) ^ fuOpType(7))
634    def isMasked (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01011".U && (fuOpType(8) ^ fuOpType(7))
635    def isStrided(fuOpType: UInt): Bool = fuOpType(6, 5) === "b10".U && (fuOpType(8) ^ fuOpType(7))
636    def isIndexed(fuOpType: UInt): Bool = fuOpType(5) && (fuOpType(8) ^ fuOpType(7))
637  }
638
639  object BKUOpType {
640
641    def clmul       = "b000000".U
642    def clmulh      = "b000001".U
643    def clmulr      = "b000010".U
644    def xpermn      = "b000100".U
645    def xpermb      = "b000101".U
646
647    def clz         = "b001000".U
648    def clzw        = "b001001".U
649    def ctz         = "b001010".U
650    def ctzw        = "b001011".U
651    def cpop        = "b001100".U
652    def cpopw       = "b001101".U
653
654    // 01xxxx is reserve
655    def aes64es     = "b100000".U
656    def aes64esm    = "b100001".U
657    def aes64ds     = "b100010".U
658    def aes64dsm    = "b100011".U
659    def aes64im     = "b100100".U
660    def aes64ks1i   = "b100101".U
661    def aes64ks2    = "b100110".U
662
663    // merge to two instruction sm4ks & sm4ed
664    def sm4ed0      = "b101000".U
665    def sm4ed1      = "b101001".U
666    def sm4ed2      = "b101010".U
667    def sm4ed3      = "b101011".U
668    def sm4ks0      = "b101100".U
669    def sm4ks1      = "b101101".U
670    def sm4ks2      = "b101110".U
671    def sm4ks3      = "b101111".U
672
673    def sha256sum0  = "b110000".U
674    def sha256sum1  = "b110001".U
675    def sha256sig0  = "b110010".U
676    def sha256sig1  = "b110011".U
677    def sha512sum0  = "b110100".U
678    def sha512sum1  = "b110101".U
679    def sha512sig0  = "b110110".U
680    def sha512sig1  = "b110111".U
681
682    def sm3p0       = "b111000".U
683    def sm3p1       = "b111001".U
684  }
685
686  object BTBtype {
687    def B = "b00".U  // branch
688    def J = "b01".U  // jump
689    def I = "b10".U  // indirect
690    def R = "b11".U  // return
691
692    def apply() = UInt(2.W)
693  }
694
695  object SelImm {
696    def IMM_X  = "b0111".U
697    def IMM_S  = "b1110".U
698    def IMM_SB = "b0001".U
699    def IMM_U  = "b0010".U
700    def IMM_UJ = "b0011".U
701    def IMM_I  = "b0100".U
702    def IMM_Z  = "b0101".U
703    def INVALID_INSTR = "b0110".U
704    def IMM_B6 = "b1000".U
705
706    def IMM_OPIVIS = "b1001".U
707    def IMM_OPIVIU = "b1010".U
708    def IMM_VSETVLI   = "b1100".U
709    def IMM_VSETIVLI  = "b1101".U
710    def IMM_LUI32 = "b1011".U
711    def IMM_VRORVI = "b1111".U
712
713    def X      = BitPat("b0000")
714
715    def apply() = UInt(4.W)
716
717    def mkString(immType: UInt) : String = {
718      val strMap = Map(
719        IMM_S.litValue         -> "S",
720        IMM_SB.litValue        -> "SB",
721        IMM_U.litValue         -> "U",
722        IMM_UJ.litValue        -> "UJ",
723        IMM_I.litValue         -> "I",
724        IMM_Z.litValue         -> "Z",
725        IMM_B6.litValue        -> "B6",
726        IMM_OPIVIS.litValue    -> "VIS",
727        IMM_OPIVIU.litValue    -> "VIU",
728        IMM_VSETVLI.litValue   -> "VSETVLI",
729        IMM_VSETIVLI.litValue  -> "VSETIVLI",
730        IMM_LUI32.litValue     -> "LUI32",
731        IMM_VRORVI.litValue    -> "VRORVI",
732        INVALID_INSTR.litValue -> "INVALID",
733      )
734      strMap(immType.litValue)
735    }
736
737    def getImmUnion(immType: UInt) : Imm = {
738      val iuMap = Map(
739        IMM_S.litValue         -> ImmUnion.S,
740        IMM_SB.litValue        -> ImmUnion.B,
741        IMM_U.litValue         -> ImmUnion.U,
742        IMM_UJ.litValue        -> ImmUnion.J,
743        IMM_I.litValue         -> ImmUnion.I,
744        IMM_Z.litValue         -> ImmUnion.Z,
745        IMM_B6.litValue        -> ImmUnion.B6,
746        IMM_OPIVIS.litValue    -> ImmUnion.OPIVIS,
747        IMM_OPIVIU.litValue    -> ImmUnion.OPIVIU,
748        IMM_VSETVLI.litValue   -> ImmUnion.VSETVLI,
749        IMM_VSETIVLI.litValue  -> ImmUnion.VSETIVLI,
750        IMM_LUI32.litValue     -> ImmUnion.LUI32,
751        IMM_VRORVI.litValue    -> ImmUnion.VRORVI,
752      )
753      iuMap(immType.litValue)
754    }
755  }
756
757  object UopSplitType {
758    def SCA_SIM          = "b000000".U //
759    def VSET             = "b010001".U // dirty: vset
760    def VEC_VVV          = "b010010".U // VEC_VVV
761    def VEC_VXV          = "b010011".U // VEC_VXV
762    def VEC_0XV          = "b010100".U // VEC_0XV
763    def VEC_VVW          = "b010101".U // VEC_VVW
764    def VEC_WVW          = "b010110".U // VEC_WVW
765    def VEC_VXW          = "b010111".U // VEC_VXW
766    def VEC_WXW          = "b011000".U // VEC_WXW
767    def VEC_WVV          = "b011001".U // VEC_WVV
768    def VEC_WXV          = "b011010".U // VEC_WXV
769    def VEC_EXT2         = "b011011".U // VF2 0 -> V
770    def VEC_EXT4         = "b011100".U // VF4 0 -> V
771    def VEC_EXT8         = "b011101".U // VF8 0 -> V
772    def VEC_VVM          = "b011110".U // VEC_VVM
773    def VEC_VXM          = "b011111".U // VEC_VXM
774    def VEC_SLIDE1UP     = "b100000".U // vslide1up.vx
775    def VEC_FSLIDE1UP    = "b100001".U // vfslide1up.vf
776    def VEC_SLIDE1DOWN   = "b100010".U // vslide1down.vx
777    def VEC_FSLIDE1DOWN  = "b100011".U // vfslide1down.vf
778    def VEC_VRED         = "b100100".U // VEC_VRED
779    def VEC_SLIDEUP      = "b100101".U // VEC_SLIDEUP
780    def VEC_SLIDEDOWN    = "b100111".U // VEC_SLIDEDOWN
781    def VEC_M0X          = "b101001".U // VEC_M0X  0MV
782    def VEC_MVV          = "b101010".U // VEC_MVV  VMV
783    def VEC_VWW          = "b101100".U //
784    def VEC_RGATHER      = "b101101".U // vrgather.vv, vrgather.vi
785    def VEC_RGATHER_VX   = "b101110".U // vrgather.vx
786    def VEC_RGATHEREI16  = "b101111".U // vrgatherei16.vv
787    def VEC_COMPRESS     = "b110000".U // vcompress.vm
788    def VEC_US_LDST      = "b110001".U // vector unit-strided load/store
789    def VEC_S_LDST       = "b110010".U // vector strided load/store
790    def VEC_I_LDST       = "b110011".U // vector indexed load/store
791    def VEC_US_FF_LD     = "b110100".U // vector unit-stride fault-only-first load
792    def VEC_VFV          = "b111000".U // VEC_VFV
793    def VEC_VFW          = "b111001".U // VEC_VFW
794    def VEC_WFW          = "b111010".U // VEC_WVW
795    def VEC_VFM          = "b111011".U // VEC_VFM
796    def VEC_VFRED        = "b111100".U // VEC_VFRED
797    def VEC_VFREDOSUM    = "b111101".U // VEC_VFREDOSUM
798    def VEC_M0M          = "b000000".U // VEC_M0M
799    def VEC_MMM          = "b000000".U // VEC_MMM
800    def VEC_MVNR         = "b000100".U // vmvnr
801
802    def AMO_CAS_W        = "b110101".U // amocas_w
803    def AMO_CAS_D        = "b110110".U // amocas_d
804    def AMO_CAS_Q        = "b110111".U // amocas_q
805    def dummy     = "b111111".U
806
807    def X = BitPat("b000000")
808
809    def apply() = UInt(6.W)
810    def needSplit(UopSplitType: UInt) = UopSplitType(4) || UopSplitType(5)
811
812    def isAmocas(UopSplitType: UInt): Bool = UopSplitType === AMO_CAS_W || UopSplitType === AMO_CAS_D || UopSplitType === AMO_CAS_Q
813  }
814
815  object ExceptionNO {
816    def instrAddrMisaligned = 0
817    def instrAccessFault    = 1
818    def illegalInstr        = 2
819    def breakPoint          = 3
820    def loadAddrMisaligned  = 4
821    def loadAccessFault     = 5
822    def storeAddrMisaligned = 6
823    def storeAccessFault    = 7
824    def ecallU              = 8
825    def ecallS              = 9
826    def ecallVS             = 10
827    def ecallM              = 11
828    def instrPageFault      = 12
829    def loadPageFault       = 13
830    // def singleStep          = 14
831    def storePageFault      = 15
832    def doubleTrap          = 16
833    def instrGuestPageFault = 20
834    def loadGuestPageFault  = 21
835    def virtualInstr        = 22
836    def storeGuestPageFault = 23
837
838    // Just alias
839    def EX_IAM    = instrAddrMisaligned
840    def EX_IAF    = instrAccessFault
841    def EX_II     = illegalInstr
842    def EX_BP     = breakPoint
843    def EX_LAM    = loadAddrMisaligned
844    def EX_LAF    = loadAccessFault
845    def EX_SAM    = storeAddrMisaligned
846    def EX_SAF    = storeAccessFault
847    def EX_UCALL  = ecallU
848    def EX_HSCALL = ecallS
849    def EX_VSCALL = ecallVS
850    def EX_MCALL  = ecallM
851    def EX_IPF    = instrPageFault
852    def EX_LPF    = loadPageFault
853    def EX_SPF    = storePageFault
854    def EX_DT     = doubleTrap
855    def EX_IGPF   = instrGuestPageFault
856    def EX_LGPF   = loadGuestPageFault
857    def EX_VI     = virtualInstr
858    def EX_SGPF   = storeGuestPageFault
859
860    def getAddressMisaligned = Seq(EX_IAM, EX_LAM, EX_SAM)
861
862    def getAccessFault = Seq(EX_IAF, EX_LAF, EX_SAF)
863
864    def getPageFault = Seq(EX_IPF, EX_LPF, EX_SPF)
865
866    def getGuestPageFault = Seq(EX_IGPF, EX_LGPF, EX_SGPF)
867
868    def getLSGuestPageFault = Seq(EX_LGPF, EX_SGPF)
869
870    def getFetchFault = Seq(EX_IAM, EX_IAF, EX_IPF)
871
872    def getLoadFault = Seq(EX_LAM, EX_LAF, EX_LPF)
873
874    def getStoreFault = Seq(EX_SAM, EX_SAF, EX_SPF)
875
876    def priorities = Seq(
877      doubleTrap,
878      breakPoint, // TODO: different BP has different priority
879      instrPageFault,
880      instrGuestPageFault,
881      instrAccessFault,
882      illegalInstr,
883      virtualInstr,
884      instrAddrMisaligned,
885      ecallM, ecallS, ecallVS, ecallU,
886      storeAddrMisaligned,
887      loadAddrMisaligned,
888      storePageFault,
889      loadPageFault,
890      storeGuestPageFault,
891      loadGuestPageFault,
892      storeAccessFault,
893      loadAccessFault
894    )
895
896    def getHigherExcpThan(excp: Int): Seq[Int] = {
897      val idx = this.priorities.indexOf(excp, 0)
898      require(idx != -1, s"The irq($excp) does not exists in IntPriority Seq")
899      this.priorities.slice(0, idx)
900    }
901
902    def all = priorities.distinct.sorted
903    def frontendSet = Seq(
904      instrAddrMisaligned,
905      instrAccessFault,
906      illegalInstr,
907      instrPageFault,
908      instrGuestPageFault,
909      virtualInstr,
910      breakPoint
911    )
912    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
913      val new_vec = Wire(ExceptionVec())
914      new_vec.foreach(_ := false.B)
915      select.foreach(i => new_vec(i) := vec(i))
916      new_vec
917    }
918    def partialSelect(vec: Vec[Bool], select: Seq[Int], unSelect: Seq[Int]): Vec[Bool] = {
919      val new_vec = Wire(ExceptionVec())
920      new_vec.foreach(_ := false.B)
921      select.diff(unSelect).foreach(i => new_vec(i) := vec(i))
922      new_vec
923    }
924    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
925    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
926    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
927      partialSelect(vec, fuConfig.exceptionOut)
928    def selectByFuAndUnSelect(vec:Vec[Bool], fuConfig: FuConfig, unSelect: Seq[Int]): Vec[Bool] =
929      partialSelect(vec, fuConfig.exceptionOut, unSelect)
930  }
931
932  object TopDownCounters extends Enumeration {
933    val NoStall = Value("NoStall") // Base
934    // frontend
935    val OverrideBubble = Value("OverrideBubble")
936    val FtqUpdateBubble = Value("FtqUpdateBubble")
937    // val ControlRedirectBubble = Value("ControlRedirectBubble")
938    val TAGEMissBubble = Value("TAGEMissBubble")
939    val SCMissBubble = Value("SCMissBubble")
940    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
941    val RASMissBubble = Value("RASMissBubble")
942    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
943    val OtherRedirectBubble = Value("OtherRedirectBubble")
944    val FtqFullStall = Value("FtqFullStall")
945
946    val ICacheMissBubble = Value("ICacheMissBubble")
947    val ITLBMissBubble = Value("ITLBMissBubble")
948    val BTBMissBubble = Value("BTBMissBubble")
949    val FetchFragBubble = Value("FetchFragBubble")
950
951    // backend
952    // long inst stall at rob head
953    val DivStall = Value("DivStall") // int div, float div/sqrt
954    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
955    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
956    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
957    // freelist full
958    val IntFlStall = Value("IntFlStall")
959    val FpFlStall = Value("FpFlStall")
960    val VecFlStall = Value("VecFlStall")
961    val V0FlStall = Value("V0FlStall")
962    val VlFlStall = Value("VlFlStall")
963    val MultiFlStall = Value("MultiFlStall")
964    // dispatch queue full
965    val IntDqStall = Value("IntDqStall")
966    val FpDqStall = Value("FpDqStall")
967    val LsDqStall = Value("LsDqStall")
968
969    // memblock
970    val LoadTLBStall = Value("LoadTLBStall")
971    val LoadL1Stall = Value("LoadL1Stall")
972    val LoadL2Stall = Value("LoadL2Stall")
973    val LoadL3Stall = Value("LoadL3Stall")
974    val LoadMemStall = Value("LoadMemStall")
975    val StoreStall = Value("StoreStall") // include store tlb miss
976    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
977
978    // xs replay (different to gem5)
979    val LoadVioReplayStall = Value("LoadVioReplayStall")
980    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
981
982    // bad speculation
983    val ControlRecoveryStall = Value("ControlRecoveryStall")
984    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
985    val OtherRecoveryStall = Value("OtherRecoveryStall")
986
987    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
988
989    val OtherCoreStall = Value("OtherCoreStall")
990
991    val NumStallReasons = Value("NumStallReasons")
992  }
993}
994