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