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