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