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