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