xref: /XiangShan/src/main/scala/xiangshan/package.scala (revision 6112d99478b9144e0e9dde27ffc43993cdaee5d4)
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
588    // atomics
589    // bit(1, 0) are size
590    // since atomics use a different fu type
591    // so we can safely reuse other load/store's encodings
592    // bit encoding: | optype(4bit) | size (2bit) |
593    def lr_w      = "b000010".U
594    def sc_w      = "b000110".U
595    def amoswap_w = "b001010".U
596    def amoadd_w  = "b001110".U
597    def amoxor_w  = "b010010".U
598    def amoand_w  = "b010110".U
599    def amoor_w   = "b011010".U
600    def amomin_w  = "b011110".U
601    def amomax_w  = "b100010".U
602    def amominu_w = "b100110".U
603    def amomaxu_w = "b101010".U
604
605    def lr_d      = "b000011".U
606    def sc_d      = "b000111".U
607    def amoswap_d = "b001011".U
608    def amoadd_d  = "b001111".U
609    def amoxor_d  = "b010011".U
610    def amoand_d  = "b010111".U
611    def amoor_d   = "b011011".U
612    def amomin_d  = "b011111".U
613    def amomax_d  = "b100011".U
614    def amominu_d = "b100111".U
615    def amomaxu_d = "b101011".U
616
617    def size(op: UInt) = op(1,0)
618
619    def getVecLSMop(fuOpType: UInt): UInt = fuOpType(6, 5)
620
621    def isAllUS  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && !fuOpType(4) && (fuOpType(8) ^ fuOpType(7))// Unit-Stride Whole Masked
622    def isUStride(fuOpType: UInt): Bool = fuOpType(6, 0) === "b00_00000".U && (fuOpType(8) ^ fuOpType(7))
623    def isWhole  (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01000".U && (fuOpType(8) ^ fuOpType(7))
624    def isMasked (fuOpType: UInt): Bool = fuOpType(6, 5) === "b00".U && fuOpType(4, 0) === "b01011".U && (fuOpType(8) ^ fuOpType(7))
625    def isStrided(fuOpType: UInt): Bool = fuOpType(6, 5) === "b10".U && (fuOpType(8) ^ fuOpType(7))
626    def isIndexed(fuOpType: UInt): Bool = fuOpType(5) && (fuOpType(8) ^ fuOpType(7))
627  }
628
629  object BKUOpType {
630
631    def clmul       = "b000000".U
632    def clmulh      = "b000001".U
633    def clmulr      = "b000010".U
634    def xpermn      = "b000100".U
635    def xpermb      = "b000101".U
636
637    def clz         = "b001000".U
638    def clzw        = "b001001".U
639    def ctz         = "b001010".U
640    def ctzw        = "b001011".U
641    def cpop        = "b001100".U
642    def cpopw       = "b001101".U
643
644    // 01xxxx is reserve
645    def aes64es     = "b100000".U
646    def aes64esm    = "b100001".U
647    def aes64ds     = "b100010".U
648    def aes64dsm    = "b100011".U
649    def aes64im     = "b100100".U
650    def aes64ks1i   = "b100101".U
651    def aes64ks2    = "b100110".U
652
653    // merge to two instruction sm4ks & sm4ed
654    def sm4ed0      = "b101000".U
655    def sm4ed1      = "b101001".U
656    def sm4ed2      = "b101010".U
657    def sm4ed3      = "b101011".U
658    def sm4ks0      = "b101100".U
659    def sm4ks1      = "b101101".U
660    def sm4ks2      = "b101110".U
661    def sm4ks3      = "b101111".U
662
663    def sha256sum0  = "b110000".U
664    def sha256sum1  = "b110001".U
665    def sha256sig0  = "b110010".U
666    def sha256sig1  = "b110011".U
667    def sha512sum0  = "b110100".U
668    def sha512sum1  = "b110101".U
669    def sha512sig0  = "b110110".U
670    def sha512sig1  = "b110111".U
671
672    def sm3p0       = "b111000".U
673    def sm3p1       = "b111001".U
674  }
675
676  object BTBtype {
677    def B = "b00".U  // branch
678    def J = "b01".U  // jump
679    def I = "b10".U  // indirect
680    def R = "b11".U  // return
681
682    def apply() = UInt(2.W)
683  }
684
685  object SelImm {
686    def IMM_X  = "b0111".U
687    def IMM_S  = "b1110".U
688    def IMM_SB = "b0001".U
689    def IMM_U  = "b0010".U
690    def IMM_UJ = "b0011".U
691    def IMM_I  = "b0100".U
692    def IMM_Z  = "b0101".U
693    def INVALID_INSTR = "b0110".U
694    def IMM_B6 = "b1000".U
695
696    def IMM_OPIVIS = "b1001".U
697    def IMM_OPIVIU = "b1010".U
698    def IMM_VSETVLI   = "b1100".U
699    def IMM_VSETIVLI  = "b1101".U
700    def IMM_LUI32 = "b1011".U
701    def IMM_VRORVI = "b1111".U
702
703    def X      = BitPat("b0000")
704
705    def apply() = UInt(4.W)
706
707    def mkString(immType: UInt) : String = {
708      val strMap = Map(
709        IMM_S.litValue         -> "S",
710        IMM_SB.litValue        -> "SB",
711        IMM_U.litValue         -> "U",
712        IMM_UJ.litValue        -> "UJ",
713        IMM_I.litValue         -> "I",
714        IMM_Z.litValue         -> "Z",
715        IMM_B6.litValue        -> "B6",
716        IMM_OPIVIS.litValue    -> "VIS",
717        IMM_OPIVIU.litValue    -> "VIU",
718        IMM_VSETVLI.litValue   -> "VSETVLI",
719        IMM_VSETIVLI.litValue  -> "VSETIVLI",
720        IMM_LUI32.litValue     -> "LUI32",
721        IMM_VRORVI.litValue    -> "VRORVI",
722        INVALID_INSTR.litValue -> "INVALID",
723      )
724      strMap(immType.litValue)
725    }
726
727    def getImmUnion(immType: UInt) : Imm = {
728      val iuMap = Map(
729        IMM_S.litValue         -> ImmUnion.S,
730        IMM_SB.litValue        -> ImmUnion.B,
731        IMM_U.litValue         -> ImmUnion.U,
732        IMM_UJ.litValue        -> ImmUnion.J,
733        IMM_I.litValue         -> ImmUnion.I,
734        IMM_Z.litValue         -> ImmUnion.Z,
735        IMM_B6.litValue        -> ImmUnion.B6,
736        IMM_OPIVIS.litValue    -> ImmUnion.OPIVIS,
737        IMM_OPIVIU.litValue    -> ImmUnion.OPIVIU,
738        IMM_VSETVLI.litValue   -> ImmUnion.VSETVLI,
739        IMM_VSETIVLI.litValue  -> ImmUnion.VSETIVLI,
740        IMM_LUI32.litValue     -> ImmUnion.LUI32,
741        IMM_VRORVI.litValue    -> ImmUnion.VRORVI,
742      )
743      iuMap(immType.litValue)
744    }
745  }
746
747  object UopSplitType {
748    def SCA_SIM          = "b000000".U //
749    def VSET             = "b010001".U // dirty: vset
750    def VEC_VVV          = "b010010".U // VEC_VVV
751    def VEC_VXV          = "b010011".U // VEC_VXV
752    def VEC_0XV          = "b010100".U // VEC_0XV
753    def VEC_VVW          = "b010101".U // VEC_VVW
754    def VEC_WVW          = "b010110".U // VEC_WVW
755    def VEC_VXW          = "b010111".U // VEC_VXW
756    def VEC_WXW          = "b011000".U // VEC_WXW
757    def VEC_WVV          = "b011001".U // VEC_WVV
758    def VEC_WXV          = "b011010".U // VEC_WXV
759    def VEC_EXT2         = "b011011".U // VF2 0 -> V
760    def VEC_EXT4         = "b011100".U // VF4 0 -> V
761    def VEC_EXT8         = "b011101".U // VF8 0 -> V
762    def VEC_VVM          = "b011110".U // VEC_VVM
763    def VEC_VXM          = "b011111".U // VEC_VXM
764    def VEC_SLIDE1UP     = "b100000".U // vslide1up.vx
765    def VEC_FSLIDE1UP    = "b100001".U // vfslide1up.vf
766    def VEC_SLIDE1DOWN   = "b100010".U // vslide1down.vx
767    def VEC_FSLIDE1DOWN  = "b100011".U // vfslide1down.vf
768    def VEC_VRED         = "b100100".U // VEC_VRED
769    def VEC_SLIDEUP      = "b100101".U // VEC_SLIDEUP
770    def VEC_SLIDEDOWN    = "b100111".U // VEC_SLIDEDOWN
771    def VEC_M0X          = "b101001".U // VEC_M0X  0MV
772    def VEC_MVV          = "b101010".U // VEC_MVV  VMV
773    def VEC_VWW          = "b101100".U //
774    def VEC_RGATHER      = "b101101".U // vrgather.vv, vrgather.vi
775    def VEC_RGATHER_VX   = "b101110".U // vrgather.vx
776    def VEC_RGATHEREI16  = "b101111".U // vrgatherei16.vv
777    def VEC_COMPRESS     = "b110000".U // vcompress.vm
778    def VEC_US_LDST      = "b110001".U // vector unit-strided load/store
779    def VEC_S_LDST       = "b110010".U // vector strided load/store
780    def VEC_I_LDST       = "b110011".U // vector indexed load/store
781    def VEC_VFV          = "b111000".U // VEC_VFV
782    def VEC_VFW          = "b111001".U // VEC_VFW
783    def VEC_WFW          = "b111010".U // VEC_WVW
784    def VEC_VFM          = "b111011".U // VEC_VFM
785    def VEC_VFRED        = "b111100".U // VEC_VFRED
786    def VEC_VFREDOSUM    = "b111101".U // VEC_VFREDOSUM
787    def VEC_M0M          = "b000000".U // VEC_M0M
788    def VEC_MMM          = "b000000".U // VEC_MMM
789    def VEC_MVNR         = "b000100".U // vmvnr
790    def dummy     = "b111111".U
791
792    def X = BitPat("b000000")
793
794    def apply() = UInt(6.W)
795    def needSplit(UopSplitType: UInt) = UopSplitType(4) || UopSplitType(5)
796  }
797
798  object ExceptionNO {
799    def instrAddrMisaligned = 0
800    def instrAccessFault    = 1
801    def illegalInstr        = 2
802    def breakPoint          = 3
803    def loadAddrMisaligned  = 4
804    def loadAccessFault     = 5
805    def storeAddrMisaligned = 6
806    def storeAccessFault    = 7
807    def ecallU              = 8
808    def ecallS              = 9
809    def ecallVS             = 10
810    def ecallM              = 11
811    def instrPageFault      = 12
812    def loadPageFault       = 13
813    // def singleStep          = 14
814    def storePageFault      = 15
815    def instrGuestPageFault = 20
816    def loadGuestPageFault  = 21
817    def virtualInstr        = 22
818    def storeGuestPageFault = 23
819
820    // Just alias
821    def EX_IAM    = instrAddrMisaligned
822    def EX_IAF    = instrAccessFault
823    def EX_II     = illegalInstr
824    def EX_BP     = breakPoint
825    def EX_LAM    = loadAddrMisaligned
826    def EX_LAF    = loadAccessFault
827    def EX_SAM    = storeAddrMisaligned
828    def EX_SAF    = storeAccessFault
829    def EX_UCALL  = ecallU
830    def EX_HSCALL = ecallS
831    def EX_VSCALL = ecallVS
832    def EX_MCALL  = ecallM
833    def EX_IPF    = instrPageFault
834    def EX_LPF    = loadPageFault
835    def EX_SPF    = storePageFault
836    def EX_IGPF   = instrGuestPageFault
837    def EX_LGPF   = loadGuestPageFault
838    def EX_VI     = virtualInstr
839    def EX_SGPF   = storeGuestPageFault
840
841    def getAddressMisaligned = Seq(EX_IAM, EX_LAM, EX_SAM)
842
843    def getAccessFault = Seq(EX_IAF, EX_LAF, EX_SAF)
844
845    def getPageFault = Seq(EX_IPF, EX_LPF, EX_SPF)
846
847    def getGuestPageFault = Seq(EX_IGPF, EX_LGPF, EX_SGPF)
848
849    def getLSGuestPageFault = Seq(EX_LGPF, EX_SGPF)
850
851    def getFetchFault = Seq(EX_IAM, EX_IAF, EX_IPF)
852
853    def getLoadFault = Seq(EX_LAM, EX_LAF, EX_LPF)
854
855    def getStoreFault = Seq(EX_SAM, EX_SAF, EX_SPF)
856
857    def priorities = Seq(
858      breakPoint, // TODO: different BP has different priority
859      instrPageFault,
860      instrGuestPageFault,
861      instrAccessFault,
862      illegalInstr,
863      virtualInstr,
864      instrAddrMisaligned,
865      ecallM, ecallS, ecallVS, ecallU,
866      storeAddrMisaligned,
867      loadAddrMisaligned,
868      storePageFault,
869      loadPageFault,
870      storeGuestPageFault,
871      loadGuestPageFault,
872      storeAccessFault,
873      loadAccessFault
874    )
875
876    def getHigherExcpThan(excp: Int): Seq[Int] = {
877      val idx = this.priorities.indexOf(excp, 0)
878      require(idx != -1, s"The irq($excp) does not exists in IntPriority Seq")
879      this.priorities.slice(0, idx)
880    }
881
882    def all = priorities.distinct.sorted
883    def frontendSet = Seq(
884      instrAddrMisaligned,
885      instrAccessFault,
886      illegalInstr,
887      instrPageFault,
888      instrGuestPageFault,
889      virtualInstr,
890      breakPoint
891    )
892    def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = {
893      val new_vec = Wire(ExceptionVec())
894      new_vec.foreach(_ := false.B)
895      select.foreach(i => new_vec(i) := vec(i))
896      new_vec
897    }
898    def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet)
899    def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all)
900    def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] =
901      partialSelect(vec, fuConfig.exceptionOut)
902  }
903
904  object TopDownCounters extends Enumeration {
905    val NoStall = Value("NoStall") // Base
906    // frontend
907    val OverrideBubble = Value("OverrideBubble")
908    val FtqUpdateBubble = Value("FtqUpdateBubble")
909    // val ControlRedirectBubble = Value("ControlRedirectBubble")
910    val TAGEMissBubble = Value("TAGEMissBubble")
911    val SCMissBubble = Value("SCMissBubble")
912    val ITTAGEMissBubble = Value("ITTAGEMissBubble")
913    val RASMissBubble = Value("RASMissBubble")
914    val MemVioRedirectBubble = Value("MemVioRedirectBubble")
915    val OtherRedirectBubble = Value("OtherRedirectBubble")
916    val FtqFullStall = Value("FtqFullStall")
917
918    val ICacheMissBubble = Value("ICacheMissBubble")
919    val ITLBMissBubble = Value("ITLBMissBubble")
920    val BTBMissBubble = Value("BTBMissBubble")
921    val FetchFragBubble = Value("FetchFragBubble")
922
923    // backend
924    // long inst stall at rob head
925    val DivStall = Value("DivStall") // int div, float div/sqrt
926    val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue
927    val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue
928    val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue
929    // freelist full
930    val IntFlStall = Value("IntFlStall")
931    val FpFlStall = Value("FpFlStall")
932    val VecFlStall = Value("VecFlStall")
933    val V0FlStall = Value("V0FlStall")
934    val VlFlStall = Value("VlFlStall")
935    val MultiFlStall = Value("MultiFlStall")
936    // dispatch queue full
937    val IntDqStall = Value("IntDqStall")
938    val FpDqStall = Value("FpDqStall")
939    val LsDqStall = Value("LsDqStall")
940
941    // memblock
942    val LoadTLBStall = Value("LoadTLBStall")
943    val LoadL1Stall = Value("LoadL1Stall")
944    val LoadL2Stall = Value("LoadL2Stall")
945    val LoadL3Stall = Value("LoadL3Stall")
946    val LoadMemStall = Value("LoadMemStall")
947    val StoreStall = Value("StoreStall") // include store tlb miss
948    val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional
949
950    // xs replay (different to gem5)
951    val LoadVioReplayStall = Value("LoadVioReplayStall")
952    val LoadMSHRReplayStall = Value("LoadMSHRReplayStall")
953
954    // bad speculation
955    val ControlRecoveryStall = Value("ControlRecoveryStall")
956    val MemVioRecoveryStall = Value("MemVioRecoveryStall")
957    val OtherRecoveryStall = Value("OtherRecoveryStall")
958
959    val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others
960
961    val OtherCoreStall = Value("OtherCoreStall")
962
963    val NumStallReasons = Value("NumStallReasons")
964  }
965}
966