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.exu._ 25import xiangshan.backend.Std 26 27package object xiangshan { 28 object SrcType { 29 def reg = "b00".U 30 def pc = "b01".U 31 def imm = "b01".U 32 def fp = "b10".U 33 34 def DC = imm // Don't Care 35 def X = BitPat("b??") 36 37 def isReg(srcType: UInt) = srcType===reg 38 def isPc(srcType: UInt) = srcType===pc 39 def isImm(srcType: UInt) = srcType===imm 40 def isFp(srcType: UInt) = srcType(1) 41 def isPcOrImm(srcType: UInt) = srcType(0) 42 def isRegOrFp(srcType: UInt) = !srcType(0) 43 def regIsFp(srcType: UInt) = srcType(1) 44 45 def apply() = UInt(2.W) 46 } 47 48 object SrcState { 49 def busy = "b0".U 50 def rdy = "b1".U 51 // def specRdy = "b10".U // speculative ready, for future use 52 def apply() = UInt(1.W) 53 } 54 55 object FuType { 56 def jmp = "b0000".U 57 def i2f = "b0001".U 58 def csr = "b0010".U 59 def alu = "b0110".U 60 def mul = "b0100".U 61 def div = "b0101".U 62 def fence = "b0011".U 63 def bku = "b0111".U 64 65 def fmac = "b1000".U 66 def fmisc = "b1011".U 67 def fDivSqrt = "b1010".U 68 69 def ldu = "b1100".U 70 def stu = "b1101".U 71 def mou = "b1111".U // for amo, lr, sc 72 73 def X = BitPat("b????") 74 75 def num = 14 76 77 def apply() = UInt(log2Up(num).W) 78 79 def isIntExu(fuType: UInt) = !fuType(3) 80 def isJumpExu(fuType: UInt) = fuType === jmp 81 def isFpExu(fuType: UInt) = fuType(3, 2) === "b10".U 82 def isMemExu(fuType: UInt) = fuType(3, 2) === "b11".U 83 def isLoadStore(fuType: UInt) = isMemExu(fuType) && !fuType(1) 84 def isStoreExu(fuType: UInt) = isMemExu(fuType) && fuType(0) 85 def isAMO(fuType: UInt) = fuType(1) 86 def isFence(fuType: UInt) = fuType === fence 87 def isDivSqrt(fuType: UInt) = fuType === div || fuType === fDivSqrt 88 def isSvinvalBegin(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.nofence && !flush 89 def isSvinval(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.sfence && !flush 90 def isSvinvalEnd(fuType: UInt, func: UInt, flush: Bool) = isFence(fuType) && func === FenceOpType.nofence && flush 91 92 93 def jmpCanAccept(fuType: UInt) = !fuType(2) 94 def mduCanAccept(fuType: UInt) = fuType(2) && !fuType(1) || fuType(2) && fuType(1) && fuType(0) 95 def aluCanAccept(fuType: UInt) = fuType(2) && fuType(1) && !fuType(0) 96 97 def fmacCanAccept(fuType: UInt) = !fuType(1) 98 def fmiscCanAccept(fuType: UInt) = fuType(1) 99 100 def loadCanAccept(fuType: UInt) = !fuType(0) 101 def storeCanAccept(fuType: UInt) = fuType(0) 102 103 def storeIsAMO(fuType: UInt) = fuType(1) 104 105 val functionNameMap = Map( 106 jmp.litValue -> "jmp", 107 i2f.litValue -> "int_to_float", 108 csr.litValue -> "csr", 109 alu.litValue -> "alu", 110 mul.litValue -> "mul", 111 div.litValue -> "div", 112 fence.litValue -> "fence", 113 bku.litValue -> "bku", 114 fmac.litValue -> "fmac", 115 fmisc.litValue -> "fmisc", 116 fDivSqrt.litValue -> "fdiv_fsqrt", 117 ldu.litValue -> "load", 118 stu.litValue -> "store", 119 mou.litValue -> "mou" 120 ) 121 } 122 123 object FuOpType { 124 def apply() = UInt(7.W) 125 def X = BitPat("b???????") 126 } 127 128 object CommitType { 129 def NORMAL = "b000".U // int/fp 130 def BRANCH = "b001".U // branch 131 def LOAD = "b010".U // load 132 def STORE = "b011".U // store 133 134 def apply() = UInt(3.W) 135 def isFused(commitType: UInt): Bool = commitType(2) 136 def isLoadStore(commitType: UInt): Bool = !isFused(commitType) && commitType(1) 137 def lsInstIsStore(commitType: UInt): Bool = commitType(0) 138 def isStore(commitType: UInt): Bool = isLoadStore(commitType) && lsInstIsStore(commitType) 139 def isBranch(commitType: UInt): Bool = commitType(0) && !commitType(1) && !isFused(commitType) 140 } 141 142 object RedirectLevel { 143 def flushAfter = "b0".U 144 def flush = "b1".U 145 146 def apply() = UInt(1.W) 147 // def isUnconditional(level: UInt) = level(1) 148 def flushItself(level: UInt) = level(0) 149 // def isException(level: UInt) = level(1) && level(0) 150 } 151 152 object ExceptionVec { 153 val ExceptionVecSize = 24 154 def apply() = Vec(ExceptionVecSize, Bool()) 155 } 156 157 object PMAMode { 158 def R = "b1".U << 0 //readable 159 def W = "b1".U << 1 //writeable 160 def X = "b1".U << 2 //executable 161 def I = "b1".U << 3 //cacheable: icache 162 def D = "b1".U << 4 //cacheable: dcache 163 def S = "b1".U << 5 //enable speculative access 164 def A = "b1".U << 6 //enable atomic operation, A imply R & W 165 def C = "b1".U << 7 //if it is cacheable is configable 166 def Reserved = "b0".U 167 168 def apply() = UInt(7.W) 169 170 def read(mode: UInt) = mode(0) 171 def write(mode: UInt) = mode(1) 172 def execute(mode: UInt) = mode(2) 173 def icache(mode: UInt) = mode(3) 174 def dcache(mode: UInt) = mode(4) 175 def speculate(mode: UInt) = mode(5) 176 def atomic(mode: UInt) = mode(6) 177 def configable_cache(mode: UInt) = mode(7) 178 179 def strToMode(s: String) = { 180 var result = 0.U(8.W) 181 if (s.toUpperCase.indexOf("R") >= 0) result = result + R 182 if (s.toUpperCase.indexOf("W") >= 0) result = result + W 183 if (s.toUpperCase.indexOf("X") >= 0) result = result + X 184 if (s.toUpperCase.indexOf("I") >= 0) result = result + I 185 if (s.toUpperCase.indexOf("D") >= 0) result = result + D 186 if (s.toUpperCase.indexOf("S") >= 0) result = result + S 187 if (s.toUpperCase.indexOf("A") >= 0) result = result + A 188 if (s.toUpperCase.indexOf("C") >= 0) result = result + C 189 result 190 } 191 } 192 193 194 object CSROpType { 195 def jmp = "b000".U 196 def wrt = "b001".U 197 def set = "b010".U 198 def clr = "b011".U 199 def wfi = "b100".U 200 def wrti = "b101".U 201 def seti = "b110".U 202 def clri = "b111".U 203 def needAccess(op: UInt): Bool = op(1, 0) =/= 0.U 204 } 205 206 // jump 207 object JumpOpType { 208 def jal = "b00".U 209 def jalr = "b01".U 210 def auipc = "b10".U 211// def call = "b11_011".U 212// def ret = "b11_100".U 213 def jumpOpisJalr(op: UInt) = op(0) 214 def jumpOpisAuipc(op: UInt) = op(1) 215 } 216 217 object FenceOpType { 218 def fence = "b10000".U 219 def sfence = "b10001".U 220 def fencei = "b10010".U 221 def hfence_v = "b10011".U 222 def hfence_g = "b10100".U 223 def nofence= "b00000".U 224 } 225 226 object ALUOpType { 227 // shift optype 228 def slliuw = "b000_0000".U // slliuw: ZEXT(src1[31:0]) << shamt 229 def sll = "b000_0001".U // sll: src1 << src2 230 231 def bclr = "b000_0010".U // bclr: src1 & ~(1 << src2[5:0]) 232 def bset = "b000_0011".U // bset: src1 | (1 << src2[5:0]) 233 def binv = "b000_0100".U // binv: src1 ^ ~(1 << src2[5:0]) 234 235 def srl = "b000_0101".U // srl: src1 >> src2 236 def bext = "b000_0110".U // bext: (src1 >> src2)[0] 237 def sra = "b000_0111".U // sra: src1 >> src2 (arithmetic) 238 239 def rol = "b000_1001".U // rol: (src1 << src2) | (src1 >> (xlen - src2)) 240 def ror = "b000_1011".U // ror: (src1 >> src2) | (src1 << (xlen - src2)) 241 242 // RV64 32bit optype 243 def addw = "b001_0000".U // addw: SEXT((src1 + src2)[31:0]) 244 def oddaddw = "b001_0001".U // oddaddw: SEXT((src1[0] + src2)[31:0]) 245 def subw = "b001_0010".U // subw: SEXT((src1 - src2)[31:0]) 246 247 def addwbit = "b001_0100".U // addwbit: (src1 + src2)[0] 248 def addwbyte = "b001_0101".U // addwbyte: (src1 + src2)[7:0] 249 def addwzexth = "b001_0110".U // addwzexth: ZEXT((src1 + src2)[15:0]) 250 def addwsexth = "b001_0111".U // addwsexth: SEXT((src1 + src2)[15:0]) 251 252 def sllw = "b001_1000".U // sllw: SEXT((src1 << src2)[31:0]) 253 def srlw = "b001_1001".U // srlw: SEXT((src1[31:0] >> src2)[31:0]) 254 def sraw = "b001_1010".U // sraw: SEXT((src1[31:0] >> src2)[31:0]) 255 def rolw = "b001_1100".U 256 def rorw = "b001_1101".U 257 258 // ADD-op 259 def adduw = "b010_0000".U // adduw: src1[31:0] + src2 260 def add = "b010_0001".U // add: src1 + src2 261 def oddadd = "b010_0010".U // oddadd: src1[0] + src2 262 263 def sr29add = "b010_0100".U // sr29add: src1[63:29] + src2 264 def sr30add = "b010_0101".U // sr30add: src1[63:30] + src2 265 def sr31add = "b010_0110".U // sr31add: src1[63:31] + src2 266 def sr32add = "b010_0111".U // sr32add: src1[63:32] + src2 267 268 def sh1adduw = "b010_1000".U // sh1adduw: {src1[31:0], 1'b0} + src2 269 def sh1add = "b010_1001".U // sh1add: {src1[62:0], 1'b0} + src2 270 def sh2adduw = "b010_1010".U // sh2add_uw: {src1[31:0], 2'b0} + src2 271 def sh2add = "b010_1011".U // sh2add: {src1[61:0], 2'b0} + src2 272 def sh3adduw = "b010_1100".U // sh3add_uw: {src1[31:0], 3'b0} + src2 273 def sh3add = "b010_1101".U // sh3add: {src1[60:0], 3'b0} + src2 274 def sh4add = "b010_1111".U // sh4add: {src1[59:0], 4'b0} + src2 275 276 // SUB-op: src1 - src2 277 def sub = "b011_0000".U 278 def sltu = "b011_0001".U 279 def slt = "b011_0010".U 280 def maxu = "b011_0100".U 281 def minu = "b011_0101".U 282 def max = "b011_0110".U 283 def min = "b011_0111".U 284 285 // branch 286 def beq = "b111_0000".U 287 def bne = "b111_0010".U 288 def blt = "b111_1000".U 289 def bge = "b111_1010".U 290 def bltu = "b111_1100".U 291 def bgeu = "b111_1110".U 292 293 // misc optype 294 def and = "b100_0000".U 295 def andn = "b100_0001".U 296 def or = "b100_0010".U 297 def orn = "b100_0011".U 298 def xor = "b100_0100".U 299 def xnor = "b100_0101".U 300 def orcb = "b100_0110".U 301 302 def sextb = "b100_1000".U 303 def packh = "b100_1001".U 304 def sexth = "b100_1010".U 305 def packw = "b100_1011".U 306 307 def revb = "b101_0000".U 308 def rev8 = "b101_0001".U 309 def pack = "b101_0010".U 310 def orh48 = "b101_0011".U 311 312 def szewl1 = "b101_1000".U 313 def szewl2 = "b101_1001".U 314 def szewl3 = "b101_1010".U 315 def byte2 = "b101_1011".U 316 317 def andlsb = "b110_0000".U 318 def andzexth = "b110_0001".U 319 def orlsb = "b110_0010".U 320 def orzexth = "b110_0011".U 321 def xorlsb = "b110_0100".U 322 def xorzexth = "b110_0101".U 323 def orcblsb = "b110_0110".U 324 def orcbzexth = "b110_0111".U 325 326 def isAddw(func: UInt) = func(6, 4) === "b001".U && !func(3) && !func(1) 327 def isSimpleLogic(func: UInt) = func(6, 4) === "b100".U && !func(0) 328 def logicToLsb(func: UInt) = Cat("b110".U(3.W), func(3, 1), 0.U(1.W)) 329 def logicToZexth(func: UInt) = Cat("b110".U(3.W), func(3, 1), 1.U(1.W)) 330 def isBranch(func: UInt) = func(6, 4) === "b111".U 331 def getBranchType(func: UInt) = func(3, 2) 332 def isBranchInvert(func: UInt) = func(1) 333 334 def apply() = UInt(7.W) 335 } 336 337 object MDUOpType { 338 // mul 339 // bit encoding: | type (2bit) | isWord(1bit) | opcode(2bit) | 340 def mul = "b00000".U 341 def mulh = "b00001".U 342 def mulhsu = "b00010".U 343 def mulhu = "b00011".U 344 def mulw = "b00100".U 345 346 def mulw7 = "b01100".U 347 348 // div 349 // bit encoding: | type (2bit) | isWord(1bit) | isSign(1bit) | opcode(1bit) | 350 def div = "b10000".U 351 def divu = "b10010".U 352 def rem = "b10001".U 353 def remu = "b10011".U 354 355 def divw = "b10100".U 356 def divuw = "b10110".U 357 def remw = "b10101".U 358 def remuw = "b10111".U 359 360 def isMul(op: UInt) = !op(4) 361 def isDiv(op: UInt) = op(4) 362 363 def isDivSign(op: UInt) = isDiv(op) && !op(1) 364 def isW(op: UInt) = op(2) 365 def isH(op: UInt) = (isDiv(op) && op(0)) || (isMul(op) && op(1, 0) =/= 0.U) 366 def getMulOp(op: UInt) = op(1, 0) 367 } 368 369 object LSUOpType { 370 // load pipeline 371 372 // normal load 373 // Note: bit(1, 0) are size, DO NOT CHANGE 374 // bit encoding: | load 0 | is unsigned(1bit) | size(2bit) | 375 def lb = "b0000".U 376 def lh = "b0001".U 377 def lw = "b0010".U 378 def ld = "b0011".U 379 def lbu = "b0100".U 380 def lhu = "b0101".U 381 def lwu = "b0110".U 382 // hypervior load 383 // bit encoding: | hlvx 1 | hlv 1 | load 0 | is unsigned(1bit) | size(2bit) | 384 def hlvb = "b10000".U 385 def hlvh = "b10001".U 386 def hlvw = "b10010".U 387 def hlvd = "b10011".U 388 def hlvbu = "b10100".U 389 def hlvhu = "b10101".U 390 def hlvwu = "b10110".U 391 def hlvxhu = "b110101".U 392 def hlvxwu = "b110110".U 393 def isHlv(op: UInt): Bool = op(4) 394 def isHlvx(op: UInt): Bool = op(5) 395 396 // Zicbop software prefetch 397 // bit encoding: | prefetch 1 | 0 | prefetch type (2bit) | 398 def prefetch_i = "b1000".U // TODO 399 def prefetch_r = "b1001".U 400 def prefetch_w = "b1010".U 401 402 def isPrefetch(op: UInt): Bool = op(3) 403 404 // store pipeline 405 // normal store 406 // bit encoding: | store 00 | size(2bit) | 407 def sb = "b0000".U 408 def sh = "b0001".U 409 def sw = "b0010".U 410 def sd = "b0011".U 411 412 //hypervisor store 413 // bit encoding: |hsv 1 | store 00 | size(2bit) | 414 def hsvb = "b10000".U 415 def hsvh = "b10001".U 416 def hsvw = "b10010".U 417 def hsvd = "b10011".U 418 def isHsv(op: UInt): Bool = op(4) 419 420 // l1 cache op 421 // bit encoding: | cbo_zero 01 | size(2bit) 11 | 422 def cbo_zero = "b0111".U 423 424 // llc op 425 // bit encoding: | prefetch 11 | suboptype(2bit) | 426 def cbo_clean = "b1100".U 427 def cbo_flush = "b1101".U 428 def cbo_inval = "b1110".U 429 430 def isCbo(op: UInt): Bool = op(3, 2) === "b11".U 431 432 // atomics 433 // bit(1, 0) are size 434 // since atomics use a different fu type 435 // so we can safely reuse other load/store's encodings 436 // bit encoding: | optype(4bit) | size (2bit) | 437 def lr_w = "b000010".U 438 def sc_w = "b000110".U 439 def amoswap_w = "b001010".U 440 def amoadd_w = "b001110".U 441 def amoxor_w = "b010010".U 442 def amoand_w = "b010110".U 443 def amoor_w = "b011010".U 444 def amomin_w = "b011110".U 445 def amomax_w = "b100010".U 446 def amominu_w = "b100110".U 447 def amomaxu_w = "b101010".U 448 449 def lr_d = "b000011".U 450 def sc_d = "b000111".U 451 def amoswap_d = "b001011".U 452 def amoadd_d = "b001111".U 453 def amoxor_d = "b010011".U 454 def amoand_d = "b010111".U 455 def amoor_d = "b011011".U 456 def amomin_d = "b011111".U 457 def amomax_d = "b100011".U 458 def amominu_d = "b100111".U 459 def amomaxu_d = "b101011".U 460 461 def size(op: UInt) = op(1,0) 462 } 463 464 object BKUOpType { 465 466 def clmul = "b000000".U 467 def clmulh = "b000001".U 468 def clmulr = "b000010".U 469 def xpermn = "b000100".U 470 def xpermb = "b000101".U 471 472 def clz = "b001000".U 473 def clzw = "b001001".U 474 def ctz = "b001010".U 475 def ctzw = "b001011".U 476 def cpop = "b001100".U 477 def cpopw = "b001101".U 478 479 // 01xxxx is reserve 480 def aes64es = "b100000".U 481 def aes64esm = "b100001".U 482 def aes64ds = "b100010".U 483 def aes64dsm = "b100011".U 484 def aes64im = "b100100".U 485 def aes64ks1i = "b100101".U 486 def aes64ks2 = "b100110".U 487 488 // merge to two instruction sm4ks & sm4ed 489 def sm4ed0 = "b101000".U 490 def sm4ed1 = "b101001".U 491 def sm4ed2 = "b101010".U 492 def sm4ed3 = "b101011".U 493 def sm4ks0 = "b101100".U 494 def sm4ks1 = "b101101".U 495 def sm4ks2 = "b101110".U 496 def sm4ks3 = "b101111".U 497 498 def sha256sum0 = "b110000".U 499 def sha256sum1 = "b110001".U 500 def sha256sig0 = "b110010".U 501 def sha256sig1 = "b110011".U 502 def sha512sum0 = "b110100".U 503 def sha512sum1 = "b110101".U 504 def sha512sig0 = "b110110".U 505 def sha512sig1 = "b110111".U 506 507 def sm3p0 = "b111000".U 508 def sm3p1 = "b111001".U 509 } 510 511 object BTBtype { 512 def B = "b00".U // branch 513 def J = "b01".U // jump 514 def I = "b10".U // indirect 515 def R = "b11".U // return 516 517 def apply() = UInt(2.W) 518 } 519 520 object SelImm { 521 def IMM_X = "b0111".U 522 def IMM_S = "b0000".U 523 def IMM_SB = "b0001".U 524 def IMM_U = "b0010".U 525 def IMM_UJ = "b0011".U 526 def IMM_I = "b0100".U 527 def IMM_Z = "b0101".U 528 def INVALID_INSTR = "b0110".U 529 def IMM_B6 = "b1000".U 530 531 def X = BitPat("b????") 532 533 def apply() = UInt(4.W) 534 } 535 536 object ExceptionNO { 537 def instrAddrMisaligned = 0 538 def instrAccessFault = 1 539 def illegalInstr = 2 540 def breakPoint = 3 541 def loadAddrMisaligned = 4 542 def loadAccessFault = 5 543 def storeAddrMisaligned = 6 544 def storeAccessFault = 7 545 def ecallU = 8 546 def ecallS = 9 547 def ecallVS = 10 548 def ecallM = 11 549 def instrPageFault = 12 550 def loadPageFault = 13 551 // def singleStep = 14 552 def storePageFault = 15 553 def instrGuestPageFault = 20 554 def loadGuestPageFault = 21 555 def virtualInstr = 22 556 def storeGuestPageFault = 23 557 def priorities = Seq( 558 breakPoint, // TODO: different BP has different priority 559 instrPageFault, 560 instrGuestPageFault, 561 instrAccessFault, 562 illegalInstr, 563 virtualInstr, 564 instrAddrMisaligned, 565 ecallM, ecallS, ecallVS, ecallU, 566 storeAddrMisaligned, 567 loadAddrMisaligned, 568 storePageFault, 569 loadPageFault, 570 storeGuestPageFault, 571 loadGuestPageFault, 572 storeAccessFault, 573 loadAccessFault 574 ) 575 def all = priorities.distinct.sorted 576 def frontendSet = Seq( 577 instrAddrMisaligned, 578 instrAccessFault, 579 illegalInstr, 580 instrPageFault, 581 instrGuestPageFault, 582 virtualInstr 583 ) 584 def partialSelect(vec: Vec[Bool], select: Seq[Int]): Vec[Bool] = { 585 val new_vec = Wire(ExceptionVec()) 586 new_vec.foreach(_ := false.B) 587 select.foreach(i => new_vec(i) := vec(i)) 588 new_vec 589 } 590 def selectFrontend(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, frontendSet) 591 def selectAll(vec: Vec[Bool]): Vec[Bool] = partialSelect(vec, ExceptionNO.all) 592 def selectByFu(vec:Vec[Bool], fuConfig: FuConfig): Vec[Bool] = 593 partialSelect(vec, fuConfig.exceptionOut) 594 def selectByExu(vec:Vec[Bool], exuConfig: ExuConfig): Vec[Bool] = 595 partialSelect(vec, exuConfig.exceptionOut) 596 def selectByExu(vec:Vec[Bool], exuConfigs: Seq[ExuConfig]): Vec[Bool] = 597 partialSelect(vec, exuConfigs.map(_.exceptionOut).reduce(_ ++ _).distinct.sorted) 598 } 599 600 def dividerGen(p: Parameters) = new DividerWrapper(p(XLen))(p) 601 def multiplierGen(p: Parameters) = new ArrayMultiplier(p(XLen) + 1)(p) 602 def aluGen(p: Parameters) = new Alu()(p) 603 def bkuGen(p: Parameters) = new Bku()(p) 604 def jmpGen(p: Parameters) = new Jump()(p) 605 def fenceGen(p: Parameters) = new Fence()(p) 606 def csrGen(p: Parameters) = new CSR()(p) 607 def i2fGen(p: Parameters) = new IntToFP()(p) 608 def fmacGen(p: Parameters) = new FMA()(p) 609 def f2iGen(p: Parameters) = new FPToInt()(p) 610 def f2fGen(p: Parameters) = new FPToFP()(p) 611 def fdivSqrtGen(p: Parameters) = new FDivSqrt()(p) 612 def stdGen(p: Parameters) = new Std()(p) 613 def mouDataGen(p: Parameters) = new Std()(p) 614 615 def f2iSel(uop: MicroOp): Bool = { 616 uop.ctrl.rfWen 617 } 618 619 def i2fSel(uop: MicroOp): Bool = { 620 uop.ctrl.fpu.fromInt 621 } 622 623 def f2fSel(uop: MicroOp): Bool = { 624 val ctrl = uop.ctrl.fpu 625 ctrl.fpWen && !ctrl.div && !ctrl.sqrt 626 } 627 628 def fdivSqrtSel(uop: MicroOp): Bool = { 629 val ctrl = uop.ctrl.fpu 630 ctrl.div || ctrl.sqrt 631 } 632 633 val aluCfg = FuConfig( 634 name = "alu", 635 fuGen = aluGen, 636 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.alu, 637 fuType = FuType.alu, 638 numIntSrc = 2, 639 numFpSrc = 0, 640 writeIntRf = true, 641 writeFpRf = false, 642 hasRedirect = true, 643 ) 644 645 val jmpCfg = FuConfig( 646 name = "jmp", 647 fuGen = jmpGen, 648 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.jmp, 649 fuType = FuType.jmp, 650 numIntSrc = 1, 651 numFpSrc = 0, 652 writeIntRf = true, 653 writeFpRf = false, 654 hasRedirect = true, 655 ) 656 657 val fenceCfg = FuConfig( 658 name = "fence", 659 fuGen = fenceGen, 660 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.fence, 661 FuType.fence, 2, 0, writeIntRf = false, writeFpRf = false, 662 latency = UncertainLatency(), exceptionOut = Seq(illegalInstr, virtualInstr), // TODO: need rewrite latency structure, not just this value, 663 flushPipe = true 664 ) 665 666 val csrCfg = FuConfig( 667 name = "csr", 668 fuGen = csrGen, 669 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.csr, 670 fuType = FuType.csr, 671 numIntSrc = 1, 672 numFpSrc = 0, 673 writeIntRf = true, 674 writeFpRf = false, 675 exceptionOut = Seq(illegalInstr, virtualInstr, breakPoint, ecallU, ecallS, ecallVS, ecallM), 676 flushPipe = true 677 ) 678 679 val i2fCfg = FuConfig( 680 name = "i2f", 681 fuGen = i2fGen, 682 fuSel = i2fSel, 683 FuType.i2f, 684 numIntSrc = 1, 685 numFpSrc = 0, 686 writeIntRf = false, 687 writeFpRf = true, 688 writeFflags = true, 689 latency = CertainLatency(2), 690 fastUopOut = true, fastImplemented = true 691 ) 692 693 val divCfg = FuConfig( 694 name = "div", 695 fuGen = dividerGen, 696 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.div, 697 FuType.div, 698 2, 699 0, 700 writeIntRf = true, 701 writeFpRf = false, 702 latency = UncertainLatency(), 703 fastUopOut = true, 704 fastImplemented = true, 705 hasInputBuffer = (true, 4, true) 706 ) 707 708 val mulCfg = FuConfig( 709 name = "mul", 710 fuGen = multiplierGen, 711 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.mul, 712 FuType.mul, 713 2, 714 0, 715 writeIntRf = true, 716 writeFpRf = false, 717 latency = CertainLatency(2), 718 fastUopOut = true, 719 fastImplemented = true 720 ) 721 722 val bkuCfg = FuConfig( 723 name = "bku", 724 fuGen = bkuGen, 725 fuSel = (uop: MicroOp) => uop.ctrl.fuType === FuType.bku, 726 fuType = FuType.bku, 727 numIntSrc = 2, 728 numFpSrc = 0, 729 writeIntRf = true, 730 writeFpRf = false, 731 latency = CertainLatency(1), 732 fastUopOut = true, 733 fastImplemented = true 734 ) 735 736 val fmacCfg = FuConfig( 737 name = "fmac", 738 fuGen = fmacGen, 739 fuSel = _ => true.B, 740 FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, writeFflags = true, 741 latency = UncertainLatency(), fastUopOut = true, fastImplemented = true 742 ) 743 744 val f2iCfg = FuConfig( 745 name = "f2i", 746 fuGen = f2iGen, 747 fuSel = f2iSel, 748 FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, writeFflags = true, latency = CertainLatency(2), 749 fastUopOut = true, fastImplemented = true 750 ) 751 752 val f2fCfg = FuConfig( 753 name = "f2f", 754 fuGen = f2fGen, 755 fuSel = f2fSel, 756 FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = CertainLatency(2), 757 fastUopOut = true, fastImplemented = true 758 ) 759 760 val fdivSqrtCfg = FuConfig( 761 name = "fdivSqrt", 762 fuGen = fdivSqrtGen, 763 fuSel = fdivSqrtSel, 764 FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, writeFflags = true, latency = UncertainLatency(), 765 fastUopOut = true, fastImplemented = true, hasInputBuffer = (true, 8, true) 766 ) 767 768 val lduCfg = FuConfig( 769 "ldu", 770 null, // DontCare 771 (uop: MicroOp) => FuType.loadCanAccept(uop.ctrl.fuType), 772 FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, 773 latency = UncertainLatency(), 774 exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault, loadGuestPageFault), 775 flushPipe = true, 776 replayInst = true, 777 hasLoadError = true 778 ) 779 780 val staCfg = FuConfig( 781 "sta", 782 null, 783 (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), 784 FuType.stu, 1, 0, writeIntRf = false, writeFpRf = false, 785 latency = UncertainLatency(), 786 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault, storeGuestPageFault) 787 ) 788 789 val stdCfg = FuConfig( 790 "std", 791 fuGen = stdGen, fuSel = (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), FuType.stu, 1, 1, 792 writeIntRf = false, writeFpRf = false, latency = CertainLatency(1) 793 ) 794 795 val mouCfg = FuConfig( 796 "mou", 797 null, 798 (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), 799 FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false, 800 latency = UncertainLatency(), exceptionOut = lduCfg.exceptionOut ++ staCfg.exceptionOut 801 ) 802 803 val mouDataCfg = FuConfig( 804 "mou", 805 mouDataGen, 806 (uop: MicroOp) => FuType.storeCanAccept(uop.ctrl.fuType), 807 FuType.mou, 1, 0, writeIntRf = false, writeFpRf = false, 808 latency = UncertainLatency() 809 ) 810 811 val JumpExeUnitCfg = ExuConfig("JmpExeUnit", "Int", Seq(jmpCfg, i2fCfg), 2, Int.MaxValue) 812 val AluExeUnitCfg = ExuConfig("AluExeUnit", "Int", Seq(aluCfg), 0, Int.MaxValue) 813 val JumpCSRExeUnitCfg = ExuConfig("JmpCSRExeUnit", "Int", Seq(jmpCfg, csrCfg, fenceCfg, i2fCfg), 2, Int.MaxValue) 814 val MulDivExeUnitCfg = ExuConfig("MulDivExeUnit", "Int", Seq(mulCfg, divCfg, bkuCfg), 1, Int.MaxValue) 815 val FmacExeUnitCfg = ExuConfig("FmacExeUnit", "Fp", Seq(fmacCfg), Int.MaxValue, 0) 816 val FmiscExeUnitCfg = ExuConfig( 817 "FmiscExeUnit", 818 "Fp", 819 Seq(f2iCfg, f2fCfg, fdivSqrtCfg), 820 Int.MaxValue, 1 821 ) 822 val LdExeUnitCfg = ExuConfig("LoadExu", "Mem", Seq(lduCfg.copy(exceptionOut = mouCfg.exceptionOut)), wbIntPriority = 0, wbFpPriority = 0, extendsExu = false) 823 val StaExeUnitCfg = ExuConfig("StaExu", "Mem", Seq(staCfg, mouCfg.copy(exceptionOut = Seq())), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false) 824 val StdExeUnitCfg = ExuConfig("StdExu", "Mem", Seq(stdCfg, mouDataCfg), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue, extendsExu = false) 825 826 object TopDownCounters extends Enumeration { 827 val NoStall = Value("NoStall") // Base 828 // frontend 829 val OverrideBubble = Value("OverrideBubble") 830 val FtqUpdateBubble = Value("FtqUpdateBubble") 831 // val ControlRedirectBubble = Value("ControlRedirectBubble") 832 val TAGEMissBubble = Value("TAGEMissBubble") 833 val SCMissBubble = Value("SCMissBubble") 834 val ITTAGEMissBubble = Value("ITTAGEMissBubble") 835 val RASMissBubble = Value("RASMissBubble") 836 val MemVioRedirectBubble = Value("MemVioRedirectBubble") 837 val OtherRedirectBubble = Value("OtherRedirectBubble") 838 val FtqFullStall = Value("FtqFullStall") 839 840 val ICacheMissBubble = Value("ICacheMissBubble") 841 val ITLBMissBubble = Value("ITLBMissBubble") 842 val BTBMissBubble = Value("BTBMissBubble") 843 val FetchFragBubble = Value("FetchFragBubble") 844 845 // backend 846 // long inst stall at rob head 847 val DivStall = Value("DivStall") // int div, float div/sqrt 848 val IntNotReadyStall = Value("IntNotReadyStall") // int-inst at rob head not issue 849 val FPNotReadyStall = Value("FPNotReadyStall") // fp-inst at rob head not issue 850 val MemNotReadyStall = Value("MemNotReadyStall") // mem-inst at rob head not issue 851 // freelist full 852 val IntFlStall = Value("IntFlStall") 853 val FpFlStall = Value("FpFlStall") 854 // dispatch queue full 855 val IntDqStall = Value("IntDqStall") 856 val FpDqStall = Value("FpDqStall") 857 val LsDqStall = Value("LsDqStall") 858 859 // memblock 860 val LoadTLBStall = Value("LoadTLBStall") 861 val LoadL1Stall = Value("LoadL1Stall") 862 val LoadL2Stall = Value("LoadL2Stall") 863 val LoadL3Stall = Value("LoadL3Stall") 864 val LoadMemStall = Value("LoadMemStall") 865 val StoreStall = Value("StoreStall") // include store tlb miss 866 val AtomicStall = Value("AtomicStall") // atomic, load reserved, store conditional 867 868 // xs replay (different to gem5) 869 val LoadVioReplayStall = Value("LoadVioReplayStall") 870 val LoadMSHRReplayStall = Value("LoadMSHRReplayStall") 871 872 // bad speculation 873 val ControlRecoveryStall = Value("ControlRecoveryStall") 874 val MemVioRecoveryStall = Value("MemVioRecoveryStall") 875 val OtherRecoveryStall = Value("OtherRecoveryStall") 876 877 val FlushedInsts = Value("FlushedInsts") // control flushed, memvio flushed, others 878 879 val OtherCoreStall = Value("OtherCoreStall") 880 881 val NumStallReasons = Value("NumStallReasons") 882 } 883} 884