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