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