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