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