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