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