xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision f7c21cb5c55b6b38a380d938e4eaff9a61e6f13e)
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    def isVsetvl  (func: UInt)  = func(6)
411    def isVsetvli (func: UInt)  = func(7)
412    def isVsetivli(func: UInt)  = func(7, 6) === 0.U
413    def isNormal  (func: UInt)  = func(1, 0) === 0.U
414    def isSetVlmax(func: UInt)  = func(setVlmaxBit)
415    def isKeepVl  (func: UInt)  = func(keepVlBit)
416    // RG: region
417    def writeIntRG(func: UInt)  = !func(5)
418    def writeVecRG(func: UInt)  = func(5)
419    def readIntRG (func: UInt)  = !func(4)
420    def readVecRG (func: UInt)  = func(4)
421    // modify fuOpType
422    def keepVl(func: UInt)      = func | (1 << keepVlBit).U
423    def setVlmax(func: UInt)    = func | (1 << setVlmaxBit).U
424  }
425
426  object BRUOpType {
427    // branch
428    def beq        = "b000_000".U
429    def bne        = "b000_001".U
430    def blt        = "b000_100".U
431    def bge        = "b000_101".U
432    def bltu       = "b001_000".U
433    def bgeu       = "b001_001".U
434
435    def getBranchType(func: UInt) = func(3, 1)
436    def isBranchInvert(func: UInt) = func(0)
437  }
438
439  object MULOpType {
440    // mul
441    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
442    def mul    = "b00000".U
443    def mulh   = "b00001".U
444    def mulhsu = "b00010".U
445    def mulhu  = "b00011".U
446    def mulw   = "b00100".U
447
448    def mulw7  = "b01100".U
449    def isSign(op: UInt) = !op(1)
450    def isW(op: UInt) = op(2)
451    def isH(op: UInt) = op(1, 0) =/= 0.U
452    def getOp(op: UInt) = Cat(op(3), op(1, 0))
453  }
454
455  object DIVOpType {
456    // div
457    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
458    def div    = "b10000".U
459    def divu   = "b10010".U
460    def rem    = "b10001".U
461    def remu   = "b10011".U
462
463    def divw   = "b10100".U
464    def divuw  = "b10110".U
465    def remw   = "b10101".U
466    def remuw  = "b10111".U
467
468    def isSign(op: UInt) = !op(1)
469    def isW(op: UInt) = op(2)
470    def isH(op: UInt) = op(0)
471  }
472
473  object MDUOpType {
474    // mul
475    // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) |
476    def mul    = "b00000".U
477    def mulh   = "b00001".U
478    def mulhsu = "b00010".U
479    def mulhu  = "b00011".U
480    def mulw   = "b00100".U
481
482    def mulw7  = "b01100".U
483
484    // div
485    // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) |
486    def div    = "b10000".U
487    def divu   = "b10010".U
488    def rem    = "b10001".U
489    def remu   = "b10011".U
490
491    def divw   = "b10100".U
492    def divuw  = "b10110".U
493    def remw   = "b10101".U
494    def remuw  = "b10111".U
495
496    def isMul(op: UInt) = !op(4)
497    def isDiv(op: UInt) = op(4)
498
499    def isDivSign(op: UInt) = isDiv(op) && !op(1)
500    def isW(op: UInt) = op(2)
501    def isH(op: UInt) = (isDiv(op) && op(0)) || (isMul(op) && op(1, 0) =/= 0.U)
502    def getMulOp(op: UInt) = op(1, 0)
503  }
504
505  object LSUOpType {
506    // The max length is 6 bits
507    // load pipeline
508
509    // normal load
510    // Note: bit(1, 0) are size, DO NOT CHANGE
511    // bit encoding: | load 0 | is unsigned(1bit) | size(2bit) |
512    def lb       = "b0000".U
513    def lh       = "b0001".U
514    def lw       = "b0010".U
515    def ld       = "b0011".U
516    def lbu      = "b0100".U
517    def lhu      = "b0101".U
518    def lwu      = "b0110".U
519    // hypervior load
520    // bit encoding: | hlv 1 | hlvx 1 | is unsigned(1bit) | size(2bit) |
521    def hlvb   = "b10000".U
522    def hlvh   = "b10001".U
523    def hlvw   = "b10010".U
524    def hlvd   = "b10011".U
525    def hlvbu  = "b10100".U
526    def hlvhu  = "b10101".U
527    def hlvwu  = "b10110".U
528    def hlvxhu = "b11101".U
529    def hlvxwu = "b11110".U
530    def isHlv(op: UInt): Bool = op(4) && (op(5) === "b0".U)
531    def isHlvx(op: UInt): Bool = op(4) && op(3) && (op(5) === "b0".U)
532
533    // Zicbop software prefetch
534    // bit encoding: | prefetch 1 | 0 | prefetch type (2bit) |
535    def prefetch_i = "b1000".U // TODO
536    def prefetch_r = "b1001".U
537    def prefetch_w = "b1010".U
538
539    def isPrefetch(op: UInt): Bool = op(3) && (op(5, 4) === "b000".U)
540
541    // store pipeline
542    // normal store
543    // bit encoding: | store 00 | size(2bit) |
544    def sb       = "b0000".U
545    def sh       = "b0001".U
546    def sw       = "b0010".U
547    def sd       = "b0011".U
548
549    //hypervisor store
550    // bit encoding: |hsv 1 | store 00 | size(2bit) |
551    def hsvb = "b10000".U
552    def hsvh = "b10001".U
553    def hsvw = "b10010".U
554    def hsvd = "b10011".U
555    def isHsv(op: UInt): Bool = op(4) && (op(5) === "b0".U)
556    // l1 cache op
557    // bit encoding: | cbo_zero 01 | size(2bit) 11 |
558    def cbo_zero  = "b0111".U
559
560    // llc op
561    // bit encoding: | prefetch 11 | suboptype(2bit) |
562    def cbo_clean = "b1100".U
563    def cbo_flush = "b1101".U
564    def cbo_inval = "b1110".U
565
566    def isCbo(op: UInt): Bool = op(3, 2) === "b11".U && (op(6, 4) === "b000".U)
567
568    // atomics
569    // bit(1, 0) are size
570    // since atomics use a different fu type
571    // so we can safely reuse other load/store's encodings
572    // bit encoding: | optype(4bit) | size (2bit) |
573    def lr_w      = "b000010".U
574    def sc_w      = "b000110".U
575    def amoswap_w = "b001010".U
576    def amoadd_w  = "b001110".U
577    def amoxor_w  = "b010010".U
578    def amoand_w  = "b010110".U
579    def amoor_w   = "b011010".U
580    def amomin_w  = "b011110".U
581    def amomax_w  = "b100010".U
582    def amominu_w = "b100110".U
583    def amomaxu_w = "b101010".U
584
585    def lr_d      = "b000011".U
586    def sc_d      = "b000111".U
587    def amoswap_d = "b001011".U
588    def amoadd_d  = "b001111".U
589    def amoxor_d  = "b010011".U
590    def amoand_d  = "b010111".U
591    def amoor_d   = "b011011".U
592    def amomin_d  = "b011111".U
593    def amomax_d  = "b100011".U
594    def amominu_d = "b100111".U
595    def amomaxu_d = "b101011".U
596
597    def size(op: UInt) = op(1,0)
598
599    def getVecLSMop(fuOpType: UInt): UInt = fuOpType(6, 5)
600
601    def isAllUS  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && !fuOpType(4) // Unit-Stride Whole Masked
602    def isUStride(fuOpType: UInt): Bool = fuOpType(6, 0) === "b00_00000".U
603    def isWhole  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01000".U
604    def isMasked (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01011".U
605    def isStrided(fuOpType: UInt): Bool = fuOpType(6, 5) === "b10".U
606    def isIndexed(fuOpType: UInt): Bool = fuOpType(5)
607  }
608
609  object BKUOpType {
610
611    def clmul       = "b000000".U
612    def clmulh      = "b000001".U
613    def clmulr      = "b000010".U
614    def xpermn      = "b000100".U
615    def xpermb      = "b000101".U
616
617    def clz         = "b001000".U
618    def clzw        = "b001001".U
619    def ctz         = "b001010".U
620    def ctzw        = "b001011".U
621    def cpop        = "b001100".U
622    def cpopw       = "b001101".U
623
624    // 01xxxx is reserve
625    def aes64es     = "b100000".U
626    def aes64esm    = "b100001".U
627    def aes64ds     = "b100010".U
628    def aes64dsm    = "b100011".U
629    def aes64im     = "b100100".U
630    def aes64ks1i   = "b100101".U
631    def aes64ks2    = "b100110".U
632
633    // merge to two instruction sm4ks & sm4ed
634    def sm4ed0      = "b101000".U
635    def sm4ed1      = "b101001".U
636    def sm4ed2      = "b101010".U
637    def sm4ed3      = "b101011".U
638    def sm4ks0      = "b101100".U
639    def sm4ks1      = "b101101".U
640    def sm4ks2      = "b101110".U
641    def sm4ks3      = "b101111".U
642
643    def sha256sum0  = "b110000".U
644    def sha256sum1  = "b110001".U
645    def sha256sig0  = "b110010".U
646    def sha256sig1  = "b110011".U
647    def sha512sum0  = "b110100".U
648    def sha512sum1  = "b110101".U
649    def sha512sig0  = "b110110".U
650    def sha512sig1  = "b110111".U
651
652    def sm3p0       = "b111000".U
653    def sm3p1       = "b111001".U
654  }
655
656  object BTBtype {
657    def B = "b00".U  // branch
658    def J = "b01".U  // jump
659    def I = "b10".U  // indirect
660    def R = "b11".U  // return
661
662    def apply() = UInt(2.W)
663  }
664
665  object SelImm {
666    def IMM_X  = "b0111".U
667    def IMM_S  = "b1110".U
668    def IMM_SB = "b0001".U
669    def IMM_U  = "b0010".U
670    def IMM_UJ = "b0011".U
671    def IMM_I  = "b0100".U
672    def IMM_Z  = "b0101".U
673    def INVALID_INSTR = "b0110".U
674    def IMM_B6 = "b1000".U
675
676    def IMM_OPIVIS = "b1001".U
677    def IMM_OPIVIU = "b1010".U
678    def IMM_VSETVLI   = "b1100".U
679    def IMM_VSETIVLI  = "b1101".U
680    def IMM_LUI32 = "b1011".U
681    def IMM_VRORVI = "b1111".U
682
683    def X      = BitPat("b0000")
684
685    def apply() = UInt(4.W)
686
687    def mkString(immType: UInt) : String = {
688      val strMap = Map(
689        IMM_S.litValue         -> "S",
690        IMM_SB.litValue        -> "SB",
691        IMM_U.litValue         -> "U",
692        IMM_UJ.litValue        -> "UJ",
693        IMM_I.litValue         -> "I",
694        IMM_Z.litValue         -> "Z",
695        IMM_B6.litValue        -> "B6",
696        IMM_OPIVIS.litValue    -> "VIS",
697        IMM_OPIVIU.litValue    -> "VIU",
698        IMM_VSETVLI.litValue   -> "VSETVLI",
699        IMM_VSETIVLI.litValue  -> "VSETIVLI",
700        IMM_LUI32.litValue     -> "LUI32",
701        IMM_VRORVI.litValue    -> "VRORVI",
702        INVALID_INSTR.litValue -> "INVALID",
703      )
704      strMap(immType.litValue)
705    }
706
707    def getImmUnion(immType: UInt) : Imm = {
708      val iuMap = Map(
709        IMM_S.litValue         -> ImmUnion.S,
710        IMM_SB.litValue        -> ImmUnion.B,
711        IMM_U.litValue         -> ImmUnion.U,
712        IMM_UJ.litValue        -> ImmUnion.J,
713        IMM_I.litValue         -> ImmUnion.I,
714        IMM_Z.litValue         -> ImmUnion.Z,
715        IMM_B6.litValue        -> ImmUnion.B6,
716        IMM_OPIVIS.litValue    -> ImmUnion.OPIVIS,
717        IMM_OPIVIU.litValue    -> ImmUnion.OPIVIU,
718        IMM_VSETVLI.litValue   -> ImmUnion.VSETVLI,
719        IMM_VSETIVLI.litValue  -> ImmUnion.VSETIVLI,
720        IMM_LUI32.litValue     -> ImmUnion.LUI32,
721        IMM_VRORVI.litValue    -> ImmUnion.VRORVI,
722      )
723      iuMap(immType.litValue)
724    }
725  }
726
727  object UopSplitType {
728    def SCA_SIM          = "b000000".U //
729    def VSET             = "b010001".U // dirty: vset
730    def VEC_VVV          = "b010010".U // VEC_VVV
731    def VEC_VXV          = "b010011".U // VEC_VXV
732    def VEC_0XV          = "b010100".U // VEC_0XV
733    def VEC_VVW          = "b010101".U // VEC_VVW
734    def VEC_WVW          = "b010110".U // VEC_WVW
735    def VEC_VXW          = "b010111".U // VEC_VXW
736    def VEC_WXW          = "b011000".U // VEC_WXW
737    def VEC_WVV          = "b011001".U // VEC_WVV
738    def VEC_WXV          = "b011010".U // VEC_WXV
739    def VEC_EXT2         = "b011011".U // VF2 0 -> V
740    def VEC_EXT4         = "b011100".U // VF4 0 -> V
741    def VEC_EXT8         = "b011101".U // VF8 0 -> V
742    def VEC_VVM          = "b011110".U // VEC_VVM
743    def VEC_VXM          = "b011111".U // VEC_VXM
744    def VEC_SLIDE1UP     = "b100000".U // vslide1up.vx
745    def VEC_FSLIDE1UP    = "b100001".U // vfslide1up.vf
746    def VEC_SLIDE1DOWN   = "b100010".U // vslide1down.vx
747    def VEC_FSLIDE1DOWN  = "b100011".U // vfslide1down.vf
748    def VEC_VRED         = "b100100".U // VEC_VRED
749    def VEC_SLIDEUP      = "b100101".U // VEC_SLIDEUP
750    def VEC_SLIDEDOWN    = "b100111".U // VEC_SLIDEDOWN
751    def VEC_M0X          = "b101001".U // VEC_M0X  0MV
752    def VEC_MVV          = "b101010".U // VEC_MVV  VMV
753    def VEC_VWW          = "b101100".U //
754    def VEC_RGATHER      = "b101101".U // vrgather.vv, vrgather.vi
755    def VEC_RGATHER_VX   = "b101110".U // vrgather.vx
756    def VEC_RGATHEREI16  = "b101111".U // vrgatherei16.vv
757    def VEC_COMPRESS     = "b110000".U // vcompress.vm
758    def VEC_US_LDST      = "b110001".U // vector unit-strided load/store
759    def VEC_S_LDST       = "b110010".U // vector strided load/store
760    def VEC_I_LDST       = "b110011".U // vector indexed load/store
761    def VEC_VFV          = "b111000".U // VEC_VFV
762    def VEC_VFW          = "b111001".U // VEC_VFW
763    def VEC_WFW          = "b111010".U // VEC_WVW
764    def VEC_VFM          = "b111011".U // VEC_VFM
765    def VEC_VFRED        = "b111100".U // VEC_VFRED
766    def VEC_VFREDOSUM    = "b111101".U // VEC_VFREDOSUM
767    def VEC_M0M          = "b000000".U // VEC_M0M
768    def VEC_MMM          = "b000000".U // VEC_MMM
769    def VEC_MVNR         = "b000100".U // vmvnr
770    def dummy     = "b111111".U
771
772    def X = BitPat("b000000")
773
774    def apply() = UInt(6.W)
775    def needSplit(UopSplitType: UInt) = UopSplitType(4) || UopSplitType(5)
776  }
777
778  object ExceptionNO {
779    def instrAddrMisaligned = 0
780    def instrAccessFault    = 1
781    def illegalInstr        = 2
782    def breakPoint          = 3
783    def loadAddrMisaligned  = 4
784    def loadAccessFault     = 5
785    def storeAddrMisaligned = 6
786    def storeAccessFault    = 7
787    def ecallU              = 8
788    def ecallS              = 9
789    def ecallVS             = 10
790    def ecallM              = 11
791    def instrPageFault      = 12
792    def loadPageFault       = 13
793    // def singleStep          = 14
794    def storePageFault      = 15
795    def instrGuestPageFault = 20
796    def loadGuestPageFault  = 21
797    def virtualInstr        = 22
798    def storeGuestPageFault = 23
799
800    // Just alias
801    def EX_IAM    = instrAddrMisaligned
802    def EX_IAF    = instrAccessFault
803    def EX_II     = illegalInstr
804    def EX_BP     = breakPoint
805    def EX_LAM    = loadAddrMisaligned
806    def EX_LAF    = loadAccessFault
807    def EX_SAM    = storeAddrMisaligned
808    def EX_SAF    = storeAccessFault
809    def EX_UCALL  = ecallU
810    def EX_HSCALL = ecallS
811    def EX_VSCALL = ecallVS
812    def EX_MCALL  = ecallM
813    def EX_IPF    = instrPageFault
814    def EX_LPF    = loadPageFault
815    def EX_SPF    = storePageFault
816    def EX_IGPF   = instrGuestPageFault
817    def EX_LGPF   = loadGuestPageFault
818    def EX_VI     = virtualInstr
819    def EX_SGPF   = storeGuestPageFault
820
821    def getAddressMisaligned = Seq(EX_IAM, EX_LAM, EX_SAM)
822
823    def getAccessFault = Seq(EX_IAF, EX_LAF, EX_SAF)
824
825    def getPageFault = Seq(EX_IPF, EX_LPF, EX_SPF)
826
827    def getGuestPageFault = Seq(EX_IGPF, EX_LGPF, EX_SGPF)
828
829    def getFetchFault = Seq(EX_IAM, EX_IAF, EX_IPF)
830
831    def getLoadFault = Seq(EX_LAM, EX_LAF, EX_LPF)
832
833    def getStoreFault = Seq(EX_SAM, EX_SAF, EX_SPF)
834
835    def priorities = Seq(
836      breakPoint, // TODO: different BP has different priority
837      instrPageFault,
838      instrGuestPageFault,
839      instrAccessFault,
840      illegalInstr,
841      virtualInstr,
842      instrAddrMisaligned,
843      ecallM, ecallS, ecallVS, ecallU,
844      storeAddrMisaligned,
845      loadAddrMisaligned,
846      storePageFault,
847      loadPageFault,
848      storeGuestPageFault,
849      loadGuestPageFault,
850      storeAccessFault,
851      loadAccessFault
852    )
853
854    def getHigherExcpThan(excp: Int): Seq[Int] = {
855      val idx = this.priorities.indexOf(excp, 0)
856      require(idx != -1, s"The irq($excp) does not exists in IntPriority Seq")
857      this.priorities.slice(0, idx)
858    }
859
860    def all = priorities.distinct.sorted
861    def frontendSet = Seq(
862      instrAddrMisaligned,
863      instrAccessFault,
864      illegalInstr,
865      instrPageFault,
866      instrGuestPageFault,
867      virtualInstr
868    )
869    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
870      val new_vec = Wire(ExceptionVec())
871      new_vec.foreach(_ := false.B)
872      select.foreach(i => new_vec(i) := vec(i))
873      new_vec
874    }
875    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
876    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
877    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
878      partialSelect(vec, fuConfig.exceptionOut)
879  }
880
881  object TopDownCounters extends Enumeration {
882    val NoStall = Value("NoStall") // Base
883    // frontend
884    val OverrideBubble = Value("OverrideBubble")
885    val FtqUpdateBubble = Value("FtqUpdateBubble")
886    // val ControlRedirectBubble = Value("ControlRedirectBubble")
887    val TAGEMissBubble = Value("TAGEMissBubble")
888    val SCMissBubble = Value("SCMissBubble")
889    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
890    val RASMissBubble = Value("RASMissBubble")
891    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
892    val OtherRedirectBubble = Value("OtherRedirectBubble")
893    val FtqFullStall = Value("FtqFullStall")
894
895    val ICacheMissBubble = Value("ICacheMissBubble")
896    val ITLBMissBubble = Value("ITLBMissBubble")
897    val BTBMissBubble = Value("BTBMissBubble")
898    val FetchFragBubble = Value("FetchFragBubble")
899
900    // backend
901    // long inst stall at rob head
902    val DivStall = Value("DivStall") // int div, float div/sqrt
903    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
904    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
905    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
906    // freelist full
907    val IntFlStall = Value("IntFlStall")
908    val FpFlStall = Value("FpFlStall")
909    val VecFlStall = Value("VecFlStall")
910    val V0FlStall = Value("V0FlStall")
911    val VlFlStall = Value("VlFlStall")
912    val MultiFlStall = Value("MultiFlStall")
913    // dispatch queue full
914    val IntDqStall = Value("IntDqStall")
915    val FpDqStall = Value("FpDqStall")
916    val LsDqStall = Value("LsDqStall")
917
918    // memblock
919    val LoadTLBStall = Value("LoadTLBStall")
920    val LoadL1Stall = Value("LoadL1Stall")
921    val LoadL2Stall = Value("LoadL2Stall")
922    val LoadL3Stall = Value("LoadL3Stall")
923    val LoadMemStall = Value("LoadMemStall")
924    val StoreStall = Value("StoreStall") // include store tlb miss
925    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
926
927    // xs replay (different to gem5)
928    val LoadVioReplayStall = Value("LoadVioReplayStall")
929    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
930
931    // bad speculation
932    val ControlRecoveryStall = Value("ControlRecoveryStall")
933    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
934    val OtherRecoveryStall = Value("OtherRecoveryStall")
935
936    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
937
938    val OtherCoreStall = Value("OtherCoreStall")
939
940    val NumStallReasons = Value("NumStallReasons")
941  }
942}
943