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