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