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