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