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 17package xiangshan 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util.BitPat.bitPatToUInt 22import chisel3.util._ 23import utility._ 24import utils._ 25import xiangshan.backend.ctrlblock.CtrlToFtqIO 26import xiangshan.backend.decode.{ImmUnion, XDecode} 27import xiangshan.backend.fu.FuType 28import xiangshan.backend.rob.RobPtr 29import xiangshan.frontend._ 30import xiangshan.mem.{LqPtr, SqPtr} 31import xiangshan.backend.Bundles.DynInst 32import xiangshan.backend.fu.vector.Bundles.VType 33import xiangshan.frontend.PreDecodeInfo 34import xiangshan.frontend.HasBPUParameter 35import xiangshan.frontend.{AllFoldedHistories, CircularGlobalHistory, GlobalHistory, ShiftingGlobalHistory} 36import xiangshan.frontend.RASEntry 37import xiangshan.frontend.BPUCtrl 38import xiangshan.frontend.FtqPtr 39import xiangshan.frontend.CGHPtr 40import xiangshan.frontend.FtqRead 41import xiangshan.frontend.FtqToCtrlIO 42import utils._ 43import utility._ 44 45import scala.math.max 46import Chisel.experimental.chiselName 47import chipsalliance.rocketchip.config.Parameters 48import chisel3.util.BitPat.bitPatToUInt 49import chisel3.util.experimental.decode.EspressoMinimizer 50import xiangshan.backend.exu.ExuConfig 51import xiangshan.backend.fu.PMPEntry 52import xiangshan.frontend.Ftq_Redirect_SRAMEntry 53import xiangshan.frontend.AllFoldedHistories 54import xiangshan.frontend.AllAheadFoldedHistoryOldestBits 55 56class ValidUndirectioned[T <: Data](gen: T) extends Bundle { 57 val valid = Bool() 58 val bits = gen.cloneType.asInstanceOf[T] 59 60} 61 62object ValidUndirectioned { 63 def apply[T <: Data](gen: T) = { 64 new ValidUndirectioned[T](gen) 65 } 66} 67 68object RSFeedbackType { 69 val tlbMiss = 0.U(4.W) 70 val mshrFull = 1.U(4.W) 71 val dataInvalid = 2.U(4.W) 72 val bankConflict = 3.U(4.W) 73 val ldVioCheckRedo = 4.U(4.W) 74 val feedbackInvalid = 7.U(4.W) 75 val issueSuccess = 8.U(4.W) 76 val rfArbitFail = 9.U(4.W) 77 val fuIdle = 10.U(4.W) 78 val fuBusy = 11.U(4.W) 79 80 def apply() = UInt(4.W) 81 82 def isStageSuccess(feedbackType: UInt) = { 83 feedbackType === issueSuccess 84 } 85 86 def isBlocked(feedbackType: UInt) = { 87 feedbackType === rfArbitFail || feedbackType === fuBusy || feedbackType === feedbackInvalid 88 } 89} 90 91class PredictorAnswer(implicit p: Parameters) extends XSBundle { 92 val hit = if (!env.FPGAPlatform) Bool() else UInt(0.W) 93 val taken = if (!env.FPGAPlatform) Bool() else UInt(0.W) 94 val target = if (!env.FPGAPlatform) UInt(VAddrBits.W) else UInt(0.W) 95} 96 97class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParameter { 98 // from backend 99 val pc = UInt(VAddrBits.W) 100 // frontend -> backend -> frontend 101 val pd = new PreDecodeInfo 102 val rasSp = UInt(log2Up(RasSize).W) 103 val rasEntry = new RASEntry 104 // val hist = new ShiftingGlobalHistory 105 val folded_hist = new AllFoldedHistories(foldedGHistInfos) 106 val afhob = new AllAheadFoldedHistoryOldestBits(foldedGHistInfos) 107 val lastBrNumOH = UInt((numBr+1).W) 108 val ghr = UInt(UbtbGHRLength.W) 109 val histPtr = new CGHPtr 110 val specCnt = Vec(numBr, UInt(10.W)) 111 // need pipeline update 112 val br_hit = Bool() 113 val predTaken = Bool() 114 val target = UInt(VAddrBits.W) 115 val taken = Bool() 116 val isMisPred = Bool() 117 val shift = UInt((log2Ceil(numBr)+1).W) 118 val addIntoHist = Bool() 119 120 def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = { 121 // this.hist := entry.ghist 122 this.folded_hist := entry.folded_hist 123 this.lastBrNumOH := entry.lastBrNumOH 124 this.afhob := entry.afhob 125 this.histPtr := entry.histPtr 126 this.rasSp := entry.rasSp 127 this.rasEntry := entry.rasTop 128 this 129 } 130} 131 132// Dequeue DecodeWidth insts from Ibuffer 133class CtrlFlow(implicit p: Parameters) extends XSBundle { 134 val instr = UInt(32.W) 135 val pc = UInt(VAddrBits.W) 136 val foldpc = UInt(MemPredPCWidth.W) 137 val exceptionVec = ExceptionVec() 138 val trigger = new TriggerCf 139 val pd = new PreDecodeInfo 140 val pred_taken = Bool() 141 val crossPageIPFFix = Bool() 142 val storeSetHit = Bool() // inst has been allocated an store set 143 val waitForRobIdx = new RobPtr // store set predicted previous store robIdx 144 // Load wait is needed 145 // load inst will not be executed until former store (predicted by mdp) addr calcuated 146 val loadWaitBit = Bool() 147 // If (loadWaitBit && loadWaitStrict), strict load wait is needed 148 // load inst will not be executed until ALL former store addr calcuated 149 val loadWaitStrict = Bool() 150 val ssid = UInt(SSIDWidth.W) 151 val ftqPtr = new FtqPtr 152 val ftqOffset = UInt(log2Up(PredictWidth).W) 153} 154 155 156class FPUCtrlSignals(implicit p: Parameters) extends XSBundle { 157 val isAddSub = Bool() // swap23 158 val typeTagIn = UInt(1.W) 159 val typeTagOut = UInt(1.W) 160 val fromInt = Bool() 161 val wflags = Bool() 162 val fpWen = Bool() 163 val fmaCmd = UInt(2.W) 164 val div = Bool() 165 val sqrt = Bool() 166 val fcvt = Bool() 167 val typ = UInt(2.W) 168 val fmt = UInt(2.W) 169 val ren3 = Bool() //TODO: remove SrcType.fp 170 val rm = UInt(3.W) 171} 172 173// Decode DecodeWidth insts at Decode Stage 174class CtrlSignals(implicit p: Parameters) extends XSBundle { 175 val debug_globalID = UInt(XLEN.W) 176 val srcType = Vec(4, SrcType()) 177 val lsrc = Vec(4, UInt(6.W)) 178 val ldest = UInt(6.W) 179 val fuType = FuType() 180 val fuOpType = FuOpType() 181 val rfWen = Bool() 182 val fpWen = Bool() 183 val vecWen = Bool() 184 val isXSTrap = Bool() 185 val noSpecExec = Bool() // wait forward 186 val blockBackward = Bool() // block backward 187 val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit 188 val uopSplitType = UopSplitType() 189 val selImm = SelImm() 190 val imm = UInt(ImmUnion.maxLen.W) 191 val commitType = CommitType() 192 val fpu = new FPUCtrlSignals 193 val uopIdx = UInt(5.W) 194 val isMove = Bool() 195 val vm = Bool() 196 val singleStep = Bool() 197 // This inst will flush all the pipe when it is the oldest inst in ROB, 198 // then replay from this inst itself 199 val replayInst = Bool() 200 201 private def allSignals = srcType.take(3) ++ Seq(fuType, fuOpType, rfWen, fpWen, vecWen, 202 isXSTrap, noSpecExec, blockBackward, flushPipe, uopSplitType, selImm) 203 204 def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]): CtrlSignals = { 205 val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decodeDefault, table, EspressoMinimizer) 206 allSignals zip decoder foreach { case (s, d) => s := d } 207 commitType := DontCare 208 this 209 } 210 211 def decode(bit: List[BitPat]): CtrlSignals = { 212 allSignals.zip(bit.map(bitPatToUInt(_))).foreach{ case (s, d) => s := d } 213 this 214 } 215 216 def isWFI: Bool = fuType === FuType.csr.U && fuOpType === CSROpType.wfi 217 def isSoftPrefetch: Bool = { 218 fuType === FuType.alu.U && fuOpType === ALUOpType.or && selImm === SelImm.IMM_I && ldest === 0.U 219 } 220 def needWriteRf: Bool = (rfWen && ldest =/= 0.U) || fpWen || vecWen 221} 222 223class CfCtrl(implicit p: Parameters) extends XSBundle { 224 val cf = new CtrlFlow 225 val ctrl = new CtrlSignals 226} 227 228class PerfDebugInfo(implicit p: Parameters) extends XSBundle { 229 val eliminatedMove = Bool() 230 // val fetchTime = UInt(XLEN.W) 231 val renameTime = UInt(XLEN.W) 232 val dispatchTime = UInt(XLEN.W) 233 val enqRsTime = UInt(XLEN.W) 234 val selectTime = UInt(XLEN.W) 235 val issueTime = UInt(XLEN.W) 236 val writebackTime = UInt(XLEN.W) 237 // val commitTime = UInt(XLEN.W) 238 val runahead_checkpoint_id = UInt(XLEN.W) 239 val tlbFirstReqTime = UInt(XLEN.W) 240 val tlbRespTime = UInt(XLEN.W) // when getting hit result (including delay in L2TLB hit) 241} 242 243// Separate LSQ 244class LSIdx(implicit p: Parameters) extends XSBundle { 245 val lqIdx = new LqPtr 246 val sqIdx = new SqPtr 247} 248 249// CfCtrl -> MicroOp at Rename Stage 250class MicroOp(implicit p: Parameters) extends CfCtrl { 251 val srcState = Vec(4, SrcState()) 252 val psrc = Vec(4, UInt(PhyRegIdxWidth.W)) 253 val pdest = UInt(PhyRegIdxWidth.W) 254 val old_pdest = UInt(PhyRegIdxWidth.W) 255 val robIdx = new RobPtr 256 val lqIdx = new LqPtr 257 val sqIdx = new SqPtr 258 val eliminatedMove = Bool() 259 val debugInfo = new PerfDebugInfo 260 def needRfRPort(index: Int, isFp: Boolean, ignoreState: Boolean = true) : Bool = { 261 val stateReady = srcState(index) === SrcState.rdy || ignoreState.B 262 val readReg = if (isFp) { 263 ctrl.srcType(index) === SrcType.fp 264 } else { 265 ctrl.srcType(index) === SrcType.reg && ctrl.lsrc(index) =/= 0.U 266 } 267 readReg && stateReady 268 } 269 def srcIsReady: Vec[Bool] = { 270 VecInit(ctrl.srcType.zip(srcState).map{ case (t, s) => SrcType.isPcOrImm(t) || s === SrcState.rdy }) 271 } 272 def clearExceptions( 273 exceptionBits: Seq[Int] = Seq(), 274 flushPipe: Boolean = false, 275 replayInst: Boolean = false 276 ): MicroOp = { 277 cf.exceptionVec.zipWithIndex.filterNot(x => exceptionBits.contains(x._2)).foreach(_._1 := false.B) 278 if (!flushPipe) { ctrl.flushPipe := false.B } 279 if (!replayInst) { ctrl.replayInst := false.B } 280 this 281 } 282 // Assume only the LUI instruction is decoded with IMM_U in ALU. 283 def isLUI: Bool = ctrl.selImm === SelImm.IMM_U && ctrl.fuType === FuType.alu 284 // This MicroOp is used to wakeup another uop (the successor: (psrc, srcType). 285 def wakeup(successor: Seq[(UInt, UInt)], exuCfg: ExuConfig): Seq[(Bool, Bool)] = { 286 successor.map{ case (src, srcType) => 287 val pdestMatch = pdest === src 288 // For state: no need to check whether src is x0/imm/pc because they are always ready. 289 val rfStateMatch = if (exuCfg.readIntRf) ctrl.rfWen else false.B 290 // FIXME: divide fpMatch and vecMatch then 291 val fpMatch = if (exuCfg.readFpRf) ctrl.fpWen else false.B 292 val vecMatch = if (exuCfg.readVecRf) ctrl.vecWen else false.B 293 val allIntFpVec = exuCfg.readIntRf && exuCfg.readFpVecRf 294 val allStateMatch = Mux(SrcType.isVp(srcType), vecMatch, Mux(SrcType.isFp(srcType), fpMatch, rfStateMatch)) 295 val stateCond = pdestMatch && (if (allIntFpVec) allStateMatch else rfStateMatch || fpMatch || vecMatch) 296 // For data: types are matched and int pdest is not $zero. 297 val rfDataMatch = if (exuCfg.readIntRf) ctrl.rfWen && src =/= 0.U else false.B 298 val dataCond = pdestMatch && (rfDataMatch && SrcType.isReg(srcType) || fpMatch && SrcType.isFp(srcType) || vecMatch && SrcType.isVp(srcType)) 299 (stateCond, dataCond) 300 } 301 } 302 // This MicroOp is used to wakeup another uop (the successor: MicroOp). 303 def wakeup(successor: MicroOp, exuCfg: ExuConfig): Seq[(Bool, Bool)] = { 304 wakeup(successor.psrc.zip(successor.ctrl.srcType), exuCfg) 305 } 306 def isJump: Bool = FuType.isJumpExu(ctrl.fuType) 307} 308 309class XSBundleWithMicroOp(implicit p: Parameters) extends XSBundle { 310 val uop = new MicroOp 311} 312 313class MicroOpRbExt(implicit p: Parameters) extends XSBundleWithMicroOp { 314 val flag = UInt(1.W) 315} 316 317class Redirect(implicit p: Parameters) extends XSBundle { 318 val robIdx = new RobPtr 319 val ftqIdx = new FtqPtr 320 val ftqOffset = UInt(log2Up(PredictWidth).W) 321 val level = RedirectLevel() 322 val interrupt = Bool() 323 val cfiUpdate = new CfiUpdateInfo 324 325 val stFtqIdx = new FtqPtr // for load violation predict 326 val stFtqOffset = UInt(log2Up(PredictWidth).W) 327 328 val debug_runahead_checkpoint_id = UInt(64.W) 329 330 def flushItself() = RedirectLevel.flushItself(level) 331} 332 333class ResetPregStateReq(implicit p: Parameters) extends XSBundle { 334 // NOTE: set isInt and isFp both to 'false' when invalid 335 val isInt = Bool() 336 val isFp = Bool() 337 val preg = UInt(PhyRegIdxWidth.W) 338} 339 340class DebugBundle(implicit p: Parameters) extends XSBundle { 341 val isMMIO = Bool() 342 val isPerfCnt = Bool() 343 val paddr = UInt(PAddrBits.W) 344 val vaddr = UInt(VAddrBits.W) 345 /* add L/S inst info in EXU */ 346 // val L1toL2TlbLatency = UInt(XLEN.W) 347 // val levelTlbHit = UInt(2.W) 348} 349 350class ExternalInterruptIO(implicit p: Parameters) extends XSBundle { 351 val mtip = Input(Bool()) 352 val msip = Input(Bool()) 353 val meip = Input(Bool()) 354 val seip = Input(Bool()) 355 val debug = Input(Bool()) 356} 357 358class CSRSpecialIO(implicit p: Parameters) extends XSBundle { 359 val exception = Flipped(ValidIO(new DynInst)) 360 val isInterrupt = Input(Bool()) 361 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 362 val trapTarget = Output(UInt(VAddrBits.W)) 363 val externalInterrupt = new ExternalInterruptIO 364 val interrupt = Output(Bool()) 365} 366 367class RabCommitInfo(implicit p: Parameters) extends XSBundle { 368 val ldest = UInt(6.W) 369 val pdest = UInt(PhyRegIdxWidth.W) 370 val old_pdest = UInt(PhyRegIdxWidth.W) 371 val rfWen = Bool() 372 val fpWen = Bool() 373 val vecWen = Bool() 374 val isMove = Bool() 375} 376 377class RabCommitIO(implicit p: Parameters) extends XSBundle { 378 val isCommit = Bool() 379 val commitValid = Vec(CommitWidth, Bool()) 380 val isWalk = Bool() 381 val walkValid = Vec(CommitWidth, Bool()) 382 val info = Vec(CommitWidth, new RabCommitInfo) 383} 384 385class DiffCommitIO(implicit p: Parameters) extends XSBundle { 386 val isCommit = Bool() 387 val commitValid = Vec(CommitWidth * MaxUopSize, Bool()) 388 389 val info = Vec(CommitWidth * MaxUopSize, new RobCommitInfo) 390} 391 392class RobCommitInfo(implicit p: Parameters) extends XSBundle { 393 val ldest = UInt(6.W) 394 val rfWen = Bool() 395 val fpWen = Bool() 396 val vecWen = Bool() 397 def fpVecWen = fpWen || vecWen 398 val wflags = Bool() 399 val commitType = CommitType() 400 val pdest = UInt(PhyRegIdxWidth.W) 401 val old_pdest = UInt(PhyRegIdxWidth.W) 402 val ftqIdx = new FtqPtr 403 val ftqOffset = UInt(log2Up(PredictWidth).W) 404 val isMove = Bool() 405 val isVset = Bool() 406 val vtype = new VType 407 408 // these should be optimized for synthesis verilog 409 val pc = UInt(VAddrBits.W) 410} 411 412class RobCommitIO(implicit p: Parameters) extends XSBundle { 413 val isCommit = Bool() 414 val commitValid = Vec(CommitWidth, Bool()) 415 416 val isWalk = Bool() 417 // valid bits optimized for walk 418 val walkValid = Vec(CommitWidth, Bool()) 419 420 val info = Vec(CommitWidth, new RobCommitInfo) 421 422 def hasWalkInstr: Bool = isWalk && walkValid.asUInt.orR 423 def hasCommitInstr: Bool = isCommit && commitValid.asUInt.orR 424} 425 426class DiffCommitIO(implicit p: Parameters) extends XSBundle { 427 val isCommit = Bool() 428 val commitValid = Vec(CommitWidth * MaxUopSize, Bool()) 429 430 val info = Vec(CommitWidth * MaxUopSize, new RobCommitInfo) 431 432 def hasCommitInstr: Bool = isCommit && commitValid.asUInt.orR 433} 434 435class RabCommitInfo(implicit p: Parameters) extends XSBundle { 436 val ldest = UInt(6.W) 437 val pdest = UInt(PhyRegIdxWidth.W) 438 val old_pdest = UInt(PhyRegIdxWidth.W) 439 val rfWen = Bool() 440 val fpWen = Bool() 441 val vecWen = Bool() 442} 443 444class RabCommitIO(implicit p: Parameters) extends XSBundle { 445 val isCommit = Bool() 446 val commitValid = Vec(CommitWidth, Bool()) 447 val isWalk = Bool() 448 val walkValid = Vec(CommitWidth, Bool()) 449 val info = Vec(CommitWidth, new RabCommitInfo) 450} 451 452class RSFeedback(implicit p: Parameters) extends XSBundle { 453 val rsIdx = UInt(log2Up(IQSizeMax).W) 454 val hit = Bool() 455 val flushState = Bool() 456 val sourceType = RSFeedbackType() 457 val dataInvalidSqIdx = new SqPtr 458} 459 460class MemRSFeedbackIO(implicit p: Parameters) extends XSBundle { 461 // Note: you need to update in implicit Parameters p before imp MemRSFeedbackIO 462 // for instance: MemRSFeedbackIO()(updateP) 463 val feedbackSlow = ValidIO(new RSFeedback()) // dcache miss queue full, dtlb miss 464 val feedbackFast = ValidIO(new RSFeedback()) // bank conflict 465} 466 467class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle { 468 // to backend end 469 val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) 470 val fromFtq = new FtqToCtrlIO 471 // from backend 472 val toFtq = Flipped(new CtrlToFtqIO) 473} 474 475class SatpStruct(implicit p: Parameters) extends XSBundle { 476 val mode = UInt(4.W) 477 val asid = UInt(16.W) 478 val ppn = UInt(44.W) 479} 480 481class TlbSatpBundle(implicit p: Parameters) extends SatpStruct { 482 val changed = Bool() 483 484 def apply(satp_value: UInt): Unit = { 485 require(satp_value.getWidth == XLEN) 486 val sa = satp_value.asTypeOf(new SatpStruct) 487 mode := sa.mode 488 asid := sa.asid 489 ppn := Cat(0.U(44-PAddrBits), sa.ppn(PAddrBits-1, 0)).asUInt() 490 changed := DataChanged(sa.asid) // when ppn is changed, software need do the flush 491 } 492} 493 494class TlbCsrBundle(implicit p: Parameters) extends XSBundle { 495 val satp = new TlbSatpBundle() 496 val priv = new Bundle { 497 val mxr = Bool() 498 val sum = Bool() 499 val imode = UInt(2.W) 500 val dmode = UInt(2.W) 501 } 502 503 override def toPrintable: Printable = { 504 p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " + 505 p"Priv mxr:${priv.mxr} sum:${priv.sum} imode:${priv.imode} dmode:${priv.dmode}" 506 } 507} 508 509class SfenceBundle(implicit p: Parameters) extends XSBundle { 510 val valid = Bool() 511 val bits = new Bundle { 512 val rs1 = Bool() 513 val rs2 = Bool() 514 val addr = UInt(VAddrBits.W) 515 val asid = UInt(AsidLength.W) 516 val flushPipe = Bool() 517 } 518 519 override def toPrintable: Printable = { 520 p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}, flushPipe:${bits.flushPipe}" 521 } 522} 523 524// Bundle for load violation predictor updating 525class MemPredUpdateReq(implicit p: Parameters) extends XSBundle { 526 val valid = Bool() 527 528 // wait table update 529 val waddr = UInt(MemPredPCWidth.W) 530 val wdata = Bool() // true.B by default 531 532 // store set update 533 // by default, ldpc/stpc should be xor folded 534 val ldpc = UInt(MemPredPCWidth.W) 535 val stpc = UInt(MemPredPCWidth.W) 536} 537 538class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle { 539 // Prefetcher 540 val l1I_pf_enable = Output(Bool()) 541 val l2_pf_enable = Output(Bool()) 542 val l1D_pf_enable = Output(Bool()) 543 val l1D_pf_train_on_hit = Output(Bool()) 544 val l1D_pf_enable_agt = Output(Bool()) 545 val l1D_pf_enable_pht = Output(Bool()) 546 val l1D_pf_active_threshold = Output(UInt(4.W)) 547 val l1D_pf_active_stride = Output(UInt(6.W)) 548 val l1D_pf_enable_stride = Output(Bool()) 549 val l2_pf_store_only = Output(Bool()) 550 // ICache 551 val icache_parity_enable = Output(Bool()) 552 // Labeled XiangShan 553 val dsid = Output(UInt(8.W)) // TODO: DsidWidth as parameter 554 // Load violation predictor 555 val lvpred_disable = Output(Bool()) 556 val no_spec_load = Output(Bool()) 557 val storeset_wait_store = Output(Bool()) 558 val storeset_no_fast_wakeup = Output(Bool()) 559 val lvpred_timeout = Output(UInt(5.W)) 560 // Branch predictor 561 val bp_ctrl = Output(new BPUCtrl) 562 // Memory Block 563 val sbuffer_threshold = Output(UInt(4.W)) 564 val ldld_vio_check_enable = Output(Bool()) 565 val soft_prefetch_enable = Output(Bool()) 566 val cache_error_enable = Output(Bool()) 567 val uncache_write_outstanding_enable = Output(Bool()) 568 // Rename 569 val fusion_enable = Output(Bool()) 570 val wfi_enable = Output(Bool()) 571 // Decode 572 val svinval_enable = Output(Bool()) 573 574 // distribute csr write signal 575 val distribute_csr = new DistributedCSRIO() 576 577 val singlestep = Output(Bool()) 578 val frontend_trigger = new FrontendTdataDistributeIO() 579 val mem_trigger = new MemTdataDistributeIO() 580 val trigger_enable = Output(Vec(10, Bool())) 581} 582 583class DistributedCSRIO(implicit p: Parameters) extends XSBundle { 584 // CSR has been written by csr inst, copies of csr should be updated 585 val w = ValidIO(new Bundle { 586 val addr = Output(UInt(12.W)) 587 val data = Output(UInt(XLEN.W)) 588 }) 589} 590 591class DistributedCSRUpdateReq(implicit p: Parameters) extends XSBundle { 592 // Request csr to be updated 593 // 594 // Note that this request will ONLY update CSR Module it self, 595 // copies of csr will NOT be updated, use it with care! 596 // 597 // For each cycle, no more than 1 DistributedCSRUpdateReq is valid 598 val w = ValidIO(new Bundle { 599 val addr = Output(UInt(12.W)) 600 val data = Output(UInt(XLEN.W)) 601 }) 602 def apply(valid: Bool, addr: UInt, data: UInt, src_description: String) = { 603 when(valid){ 604 w.bits.addr := addr 605 w.bits.data := data 606 } 607 println("Distributed CSR update req registered for " + src_description) 608 } 609} 610 611class L1CacheErrorInfo(implicit p: Parameters) extends XSBundle { 612 // L1CacheErrorInfo is also used to encode customized CACHE_ERROR CSR 613 val source = Output(new Bundle() { 614 val tag = Bool() // l1 tag array 615 val data = Bool() // l1 data array 616 val l2 = Bool() 617 }) 618 val opType = Output(new Bundle() { 619 val fetch = Bool() 620 val load = Bool() 621 val store = Bool() 622 val probe = Bool() 623 val release = Bool() 624 val atom = Bool() 625 }) 626 val paddr = Output(UInt(PAddrBits.W)) 627 628 // report error and paddr to beu 629 // bus error unit will receive error info iff ecc_error.valid 630 val report_to_beu = Output(Bool()) 631 632 // there is an valid error 633 // l1 cache error will always be report to CACHE_ERROR csr 634 val valid = Output(Bool()) 635 636 def toL1BusErrorUnitInfo(): L1BusErrorUnitInfo = { 637 val beu_info = Wire(new L1BusErrorUnitInfo) 638 beu_info.ecc_error.valid := report_to_beu 639 beu_info.ecc_error.bits := paddr 640 beu_info 641 } 642} 643 644/* TODO how to trigger on next inst? 6451. If hit is determined at frontend, then set a "next instr" trap at dispatch like singlestep 6462. If it is determined at Load(meaning it must be "hit after", then it must not be a jump. So we can let it commit and set 647xret csr to pc + 4/ + 2 6482.5 The problem is to let it commit. This is the real TODO 6493. If it is load and hit before just treat it as regular load exception 650 */ 651 652// This bundle carries trigger hit info along the pipeline 653// Now there are 10 triggers divided into 5 groups of 2 654// These groups are 655// (if if) (store store) (load loid) (if store) (if load) 656 657// Triggers in the same group can chain, meaning that they only 658// fire is both triggers in the group matches (the triggerHitVec bit is asserted) 659// Chaining of trigger No. (2i) and (2i+1) is indicated by triggerChainVec(i) 660// Timing of 0 means trap at current inst, 1 means trap at next inst 661// Chaining and timing and the validness of a trigger is controlled by csr 662// In two chained triggers, if they have different timing, both won't fire 663//class TriggerCf (implicit p: Parameters) extends XSBundle { 664// val triggerHitVec = Vec(10, Bool()) 665// val triggerTiming = Vec(10, Bool()) 666// val triggerChainVec = Vec(5, Bool()) 667//} 668 669class TriggerCf(implicit p: Parameters) extends XSBundle { 670 // frontend 671 val frontendHit = Vec(4, Bool()) 672// val frontendTiming = Vec(4, Bool()) 673// val frontendHitNext = Vec(4, Bool()) 674 675// val frontendException = Bool() 676 // backend 677 val backendEn = Vec(2, Bool()) // Hit(6) && chain(4) , Hit(8) && chain(4) 678 val backendHit = Vec(6, Bool()) 679// val backendTiming = Vec(6, Bool()) // trigger enable fro chain 680 681 // Two situations not allowed: 682 // 1. load data comparison 683 // 2. store chaining with store 684 def getHitFrontend = frontendHit.reduce(_ || _) 685 def getHitBackend = backendHit.reduce(_ || _) 686 def hit = getHitFrontend || getHitBackend 687 def clear(): Unit = { 688 frontendHit.foreach(_ := false.B) 689 backendEn.foreach(_ := false.B) 690 backendHit.foreach(_ := false.B) 691 } 692} 693 694// these 3 bundles help distribute trigger control signals from CSR 695// to Frontend, Load and Store. 696class FrontendTdataDistributeIO(implicit p: Parameters) extends XSBundle { 697 val t = Valid(new Bundle { 698 val addr = Output(UInt(2.W)) 699 val tdata = new MatchTriggerIO 700 }) 701 } 702 703class MemTdataDistributeIO(implicit p: Parameters) extends XSBundle { 704 val t = Valid(new Bundle { 705 val addr = Output(UInt(3.W)) 706 val tdata = new MatchTriggerIO 707 }) 708} 709 710class MatchTriggerIO(implicit p: Parameters) extends XSBundle { 711 val matchType = Output(UInt(2.W)) 712 val select = Output(Bool()) 713 val timing = Output(Bool()) 714 val action = Output(Bool()) 715 val chain = Output(Bool()) 716 val tdata2 = Output(UInt(64.W)) 717} 718