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