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