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