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 206 private def allSignals = srcType.take(3) ++ Seq(fuType, fuOpType, rfWen, fpWen, vecWen, 207 isXSTrap, noSpecExec, blockBackward, flushPipe, uopSplitType, selImm) 208 209 def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]): CtrlSignals = { 210 val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decodeDefault, table, EspressoMinimizer) 211 allSignals zip decoder foreach { case (s, d) => s := d } 212 commitType := DontCare 213 this 214 } 215 216 def decode(bit: List[BitPat]): CtrlSignals = { 217 allSignals.zip(bit.map(bitPatToUInt(_))).foreach{ case (s, d) => s := d } 218 this 219 } 220 221 def isWFI: Bool = fuType === FuType.csr.U && fuOpType === CSROpType.wfi 222 def isSoftPrefetch: Bool = { 223 fuType === FuType.alu.U && fuOpType === ALUOpType.or && selImm === SelImm.IMM_I && ldest === 0.U 224 } 225 def needWriteRf: Bool = (rfWen && ldest =/= 0.U) || fpWen || vecWen 226} 227 228class CfCtrl(implicit p: Parameters) extends XSBundle { 229 val cf = new CtrlFlow 230 val ctrl = new CtrlSignals 231} 232 233class PerfDebugInfo(implicit p: Parameters) extends XSBundle { 234 val eliminatedMove = Bool() 235 // val fetchTime = UInt(XLEN.W) 236 val renameTime = UInt(XLEN.W) 237 val dispatchTime = UInt(XLEN.W) 238 val enqRsTime = UInt(XLEN.W) 239 val selectTime = UInt(XLEN.W) 240 val issueTime = UInt(XLEN.W) 241 val writebackTime = UInt(XLEN.W) 242 // val commitTime = UInt(XLEN.W) 243 val runahead_checkpoint_id = UInt(XLEN.W) 244 val tlbFirstReqTime = UInt(XLEN.W) 245 val tlbRespTime = UInt(XLEN.W) // when getting hit result (including delay in L2TLB hit) 246} 247 248// Separate LSQ 249class LSIdx(implicit p: Parameters) extends XSBundle { 250 val lqIdx = new LqPtr 251 val sqIdx = new SqPtr 252} 253 254// CfCtrl -> MicroOp at Rename Stage 255class MicroOp(implicit p: Parameters) extends CfCtrl { 256 val srcState = Vec(4, SrcState()) 257 val psrc = Vec(4, UInt(PhyRegIdxWidth.W)) 258 val pdest = UInt(PhyRegIdxWidth.W) 259 val robIdx = new RobPtr 260 val lqIdx = new LqPtr 261 val sqIdx = new SqPtr 262 val eliminatedMove = Bool() 263 val snapshot = Bool() 264 val debugInfo = new PerfDebugInfo 265 def needRfRPort(index: Int, isFp: Boolean, ignoreState: Boolean = true) : Bool = { 266 val stateReady = srcState(index) === SrcState.rdy || ignoreState.B 267 val readReg = if (isFp) { 268 ctrl.srcType(index) === SrcType.fp 269 } else { 270 ctrl.srcType(index) === SrcType.reg && ctrl.lsrc(index) =/= 0.U 271 } 272 readReg && stateReady 273 } 274 def srcIsReady: Vec[Bool] = { 275 VecInit(ctrl.srcType.zip(srcState).map{ case (t, s) => SrcType.isPcOrImm(t) || s === SrcState.rdy }) 276 } 277 def clearExceptions( 278 exceptionBits: Seq[Int] = Seq(), 279 flushPipe: Boolean = false, 280 replayInst: Boolean = false 281 ): MicroOp = { 282 cf.exceptionVec.zipWithIndex.filterNot(x => exceptionBits.contains(x._2)).foreach(_._1 := false.B) 283 if (!flushPipe) { ctrl.flushPipe := false.B } 284 if (!replayInst) { ctrl.replayInst := false.B } 285 this 286 } 287} 288 289class XSBundleWithMicroOp(implicit p: Parameters) extends XSBundle { 290 val uop = new DynInst 291} 292 293class MicroOpRbExt(implicit p: Parameters) extends XSBundleWithMicroOp { 294 val flag = UInt(1.W) 295} 296 297class Redirect(implicit p: Parameters) extends XSBundle { 298 val isRVC = Bool() 299 val robIdx = new RobPtr 300 val ftqIdx = new FtqPtr 301 val ftqOffset = UInt(log2Up(PredictWidth).W) 302 val level = RedirectLevel() 303 val interrupt = Bool() 304 val cfiUpdate = new CfiUpdateInfo 305 306 val stFtqIdx = new FtqPtr // for load violation predict 307 val stFtqOffset = UInt(log2Up(PredictWidth).W) 308 309 val debug_runahead_checkpoint_id = UInt(64.W) 310 val debugIsCtrl = Bool() 311 val debugIsMemVio = Bool() 312 313 def flushItself() = RedirectLevel.flushItself(level) 314} 315 316class ResetPregStateReq(implicit p: Parameters) extends XSBundle { 317 // NOTE: set isInt and isFp both to 'false' when invalid 318 val isInt = Bool() 319 val isFp = Bool() 320 val preg = UInt(PhyRegIdxWidth.W) 321} 322 323class DebugBundle(implicit p: Parameters) extends XSBundle { 324 val isMMIO = Bool() 325 val isPerfCnt = Bool() 326 val paddr = UInt(PAddrBits.W) 327 val vaddr = UInt(VAddrBits.W) 328 /* add L/S inst info in EXU */ 329 // val L1toL2TlbLatency = UInt(XLEN.W) 330 // val levelTlbHit = UInt(2.W) 331} 332 333class ExternalInterruptIO(implicit p: Parameters) extends XSBundle { 334 val mtip = Input(Bool()) 335 val msip = Input(Bool()) 336 val meip = Input(Bool()) 337 val seip = Input(Bool()) 338 val debug = Input(Bool()) 339} 340 341class CSRSpecialIO(implicit p: Parameters) extends XSBundle { 342 val exception = Flipped(ValidIO(new DynInst)) 343 val isInterrupt = Input(Bool()) 344 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 345 val trapTarget = Output(UInt(VAddrBits.W)) 346 val externalInterrupt = new ExternalInterruptIO 347 val interrupt = Output(Bool()) 348} 349 350class RabCommitInfo(implicit p: Parameters) extends XSBundle { 351 val ldest = UInt(6.W) 352 val pdest = UInt(PhyRegIdxWidth.W) 353 val old_pdest = UInt(PhyRegIdxWidth.W) 354 val rfWen = Bool() 355 val fpWen = Bool() 356 val vecWen = Bool() 357 val isMove = Bool() 358} 359 360class RabCommitIO(implicit p: Parameters) extends XSBundle { 361 val isCommit = Bool() 362 val commitValid = Vec(CommitWidth, Bool()) 363 val isWalk = Bool() 364 val walkValid = Vec(CommitWidth, Bool()) 365 val info = Vec(CommitWidth, new RabCommitInfo) 366} 367 368class DiffCommitIO(implicit p: Parameters) extends XSBundle { 369 val isCommit = Bool() 370 val commitValid = Vec(CommitWidth * MaxUopSize, Bool()) 371 372 val info = Vec(CommitWidth * MaxUopSize, new RobCommitInfo) 373} 374 375class RobCommitInfo(implicit p: Parameters) extends XSBundle { 376 val ldest = UInt(6.W) 377 val rfWen = Bool() 378 val fpWen = Bool() 379 val vecWen = Bool() 380 def fpVecWen = fpWen || vecWen 381 val wflags = Bool() 382 val commitType = CommitType() 383 val pdest = UInt(PhyRegIdxWidth.W) 384 val ftqIdx = new FtqPtr 385 val ftqOffset = UInt(log2Up(PredictWidth).W) 386 val isMove = Bool() 387 val isRVC = Bool() 388 val isVset = Bool() 389 val vtype = new VType 390 391 // these should be optimized for synthesis verilog 392 val pc = UInt(VAddrBits.W) 393} 394 395class RobCommitIO(implicit p: Parameters) extends XSBundle { 396 val isCommit = Bool() 397 val commitValid = Vec(CommitWidth, Bool()) 398 399 val isWalk = Bool() 400 // valid bits optimized for walk 401 val walkValid = Vec(CommitWidth, Bool()) 402 403 val info = Vec(CommitWidth, new RobCommitInfo) 404 val robIdx = Vec(CommitWidth, new RobPtr) 405 406 def hasWalkInstr: Bool = isWalk && walkValid.asUInt.orR 407 def hasCommitInstr: Bool = isCommit && commitValid.asUInt.orR 408} 409 410class SnapshotPort(implicit p: Parameters) extends XSBundle { 411 val snptEnq = Bool() 412 val snptDeq = Bool() 413 val useSnpt = Bool() 414 val snptSelect = UInt(log2Ceil(RenameSnapshotNum).W) 415} 416 417class RSFeedback(implicit p: Parameters) extends XSBundle { 418 val rsIdx = UInt(log2Up(IQSizeMax).W) 419 val hit = Bool() 420 val flushState = Bool() 421 val sourceType = RSFeedbackType() 422 val dataInvalidSqIdx = new SqPtr 423} 424 425class MemRSFeedbackIO(implicit p: Parameters) extends XSBundle { 426 // Note: you need to update in implicit Parameters p before imp MemRSFeedbackIO 427 // for instance: MemRSFeedbackIO()(updateP) 428 val feedbackSlow = ValidIO(new RSFeedback()) // dcache miss queue full, dtlb miss 429 val feedbackFast = ValidIO(new RSFeedback()) // bank conflict 430} 431 432class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle { 433 // to backend end 434 val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) 435 val stallReason = new StallReasonIO(DecodeWidth) 436 val fromFtq = new FtqToCtrlIO 437 // from backend 438 val toFtq = Flipped(new CtrlToFtqIO) 439} 440 441class SatpStruct(implicit p: Parameters) extends XSBundle { 442 val mode = UInt(4.W) 443 val asid = UInt(16.W) 444 val ppn = UInt(44.W) 445} 446 447class TlbSatpBundle(implicit p: Parameters) extends SatpStruct { 448 val changed = Bool() 449 450 def apply(satp_value: UInt): Unit = { 451 require(satp_value.getWidth == XLEN) 452 val sa = satp_value.asTypeOf(new SatpStruct) 453 mode := sa.mode 454 asid := sa.asid 455 ppn := Cat(0.U(44-PAddrBits), sa.ppn(PAddrBits-1, 0)).asUInt() 456 changed := DataChanged(sa.asid) // when ppn is changed, software need do the flush 457 } 458} 459 460class TlbCsrBundle(implicit p: Parameters) extends XSBundle { 461 val satp = new TlbSatpBundle() 462 val priv = new Bundle { 463 val mxr = Bool() 464 val sum = Bool() 465 val imode = UInt(2.W) 466 val dmode = UInt(2.W) 467 } 468 469 override def toPrintable: Printable = { 470 p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " + 471 p"Priv mxr:${priv.mxr} sum:${priv.sum} imode:${priv.imode} dmode:${priv.dmode}" 472 } 473} 474 475class SfenceBundle(implicit p: Parameters) extends XSBundle { 476 val valid = Bool() 477 val bits = new Bundle { 478 val rs1 = Bool() 479 val rs2 = Bool() 480 val addr = UInt(VAddrBits.W) 481 val asid = UInt(AsidLength.W) 482 val flushPipe = Bool() 483 } 484 485 override def toPrintable: Printable = { 486 p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}, flushPipe:${bits.flushPipe}" 487 } 488} 489 490// Bundle for load violation predictor updating 491class MemPredUpdateReq(implicit p: Parameters) extends XSBundle { 492 val valid = Bool() 493 494 // wait table update 495 val waddr = UInt(MemPredPCWidth.W) 496 val wdata = Bool() // true.B by default 497 498 // store set update 499 // by default, ldpc/stpc should be xor folded 500 val ldpc = UInt(MemPredPCWidth.W) 501 val stpc = UInt(MemPredPCWidth.W) 502} 503 504class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle { 505 // Prefetcher 506 val l1I_pf_enable = Output(Bool()) 507 val l2_pf_enable = Output(Bool()) 508 val l1D_pf_enable = Output(Bool()) 509 val l1D_pf_train_on_hit = Output(Bool()) 510 val l1D_pf_enable_agt = Output(Bool()) 511 val l1D_pf_enable_pht = Output(Bool()) 512 val l1D_pf_active_threshold = Output(UInt(4.W)) 513 val l1D_pf_active_stride = Output(UInt(6.W)) 514 val l1D_pf_enable_stride = Output(Bool()) 515 val l2_pf_store_only = Output(Bool()) 516 // ICache 517 val icache_parity_enable = Output(Bool()) 518 // Labeled XiangShan 519 val dsid = Output(UInt(8.W)) // TODO: DsidWidth as parameter 520 // Load violation predictor 521 val lvpred_disable = Output(Bool()) 522 val no_spec_load = Output(Bool()) 523 val storeset_wait_store = Output(Bool()) 524 val storeset_no_fast_wakeup = Output(Bool()) 525 val lvpred_timeout = Output(UInt(5.W)) 526 // Branch predictor 527 val bp_ctrl = Output(new BPUCtrl) 528 // Memory Block 529 val sbuffer_threshold = Output(UInt(4.W)) 530 val ldld_vio_check_enable = Output(Bool()) 531 val soft_prefetch_enable = Output(Bool()) 532 val cache_error_enable = Output(Bool()) 533 val uncache_write_outstanding_enable = Output(Bool()) 534 // Rename 535 val fusion_enable = Output(Bool()) 536 val wfi_enable = Output(Bool()) 537 // Decode 538 val svinval_enable = Output(Bool()) 539 540 // distribute csr write signal 541 val distribute_csr = new DistributedCSRIO() 542 543 val singlestep = Output(Bool()) 544 val frontend_trigger = new FrontendTdataDistributeIO() 545 val mem_trigger = new MemTdataDistributeIO() 546 val trigger_enable = Output(Vec(10, Bool())) 547} 548 549class DistributedCSRIO(implicit p: Parameters) extends XSBundle { 550 // CSR has been written by csr inst, copies of csr should be updated 551 val w = ValidIO(new Bundle { 552 val addr = Output(UInt(12.W)) 553 val data = Output(UInt(XLEN.W)) 554 }) 555} 556 557class DistributedCSRUpdateReq(implicit p: Parameters) extends XSBundle { 558 // Request csr to be updated 559 // 560 // Note that this request will ONLY update CSR Module it self, 561 // copies of csr will NOT be updated, use it with care! 562 // 563 // For each cycle, no more than 1 DistributedCSRUpdateReq is valid 564 val w = ValidIO(new Bundle { 565 val addr = Output(UInt(12.W)) 566 val data = Output(UInt(XLEN.W)) 567 }) 568 def apply(valid: Bool, addr: UInt, data: UInt, src_description: String) = { 569 when(valid){ 570 w.bits.addr := addr 571 w.bits.data := data 572 } 573 println("Distributed CSR update req registered for " + src_description) 574 } 575} 576 577class L1CacheErrorInfo(implicit p: Parameters) extends XSBundle { 578 // L1CacheErrorInfo is also used to encode customized CACHE_ERROR CSR 579 val source = Output(new Bundle() { 580 val tag = Bool() // l1 tag array 581 val data = Bool() // l1 data array 582 val l2 = Bool() 583 }) 584 val opType = Output(new Bundle() { 585 val fetch = Bool() 586 val load = Bool() 587 val store = Bool() 588 val probe = Bool() 589 val release = Bool() 590 val atom = Bool() 591 }) 592 val paddr = Output(UInt(PAddrBits.W)) 593 594 // report error and paddr to beu 595 // bus error unit will receive error info iff ecc_error.valid 596 val report_to_beu = Output(Bool()) 597 598 // there is an valid error 599 // l1 cache error will always be report to CACHE_ERROR csr 600 val valid = Output(Bool()) 601 602 def toL1BusErrorUnitInfo(): L1BusErrorUnitInfo = { 603 val beu_info = Wire(new L1BusErrorUnitInfo) 604 beu_info.ecc_error.valid := report_to_beu 605 beu_info.ecc_error.bits := paddr 606 beu_info 607 } 608} 609 610/* TODO how to trigger on next inst? 6111. If hit is determined at frontend, then set a "next instr" trap at dispatch like singlestep 6122. 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 613xret csr to pc + 4/ + 2 6142.5 The problem is to let it commit. This is the real TODO 6153. If it is load and hit before just treat it as regular load exception 616 */ 617 618// This bundle carries trigger hit info along the pipeline 619// Now there are 10 triggers divided into 5 groups of 2 620// These groups are 621// (if if) (store store) (load loid) (if store) (if load) 622 623// Triggers in the same group can chain, meaning that they only 624// fire is both triggers in the group matches (the triggerHitVec bit is asserted) 625// Chaining of trigger No. (2i) and (2i+1) is indicated by triggerChainVec(i) 626// Timing of 0 means trap at current inst, 1 means trap at next inst 627// Chaining and timing and the validness of a trigger is controlled by csr 628// In two chained triggers, if they have different timing, both won't fire 629//class TriggerCf (implicit p: Parameters) extends XSBundle { 630// val triggerHitVec = Vec(10, Bool()) 631// val triggerTiming = Vec(10, Bool()) 632// val triggerChainVec = Vec(5, Bool()) 633//} 634 635class TriggerCf(implicit p: Parameters) extends XSBundle { 636 // frontend 637 val frontendHit = Vec(4, Bool()) 638// val frontendTiming = Vec(4, Bool()) 639// val frontendHitNext = Vec(4, Bool()) 640 641// val frontendException = Bool() 642 // backend 643 val backendEn = Vec(2, Bool()) // Hit(6) && chain(4) , Hit(8) && chain(4) 644 val backendHit = Vec(6, Bool()) 645// val backendTiming = Vec(6, Bool()) // trigger enable fro chain 646 647 // Two situations not allowed: 648 // 1. load data comparison 649 // 2. store chaining with store 650 def getHitFrontend = frontendHit.reduce(_ || _) 651 def getHitBackend = backendHit.reduce(_ || _) 652 def hit = getHitFrontend || getHitBackend 653 def clear(): Unit = { 654 frontendHit.foreach(_ := false.B) 655 backendEn.foreach(_ := false.B) 656 backendHit.foreach(_ := false.B) 657 } 658} 659 660// these 3 bundles help distribute trigger control signals from CSR 661// to Frontend, Load and Store. 662class FrontendTdataDistributeIO(implicit p: Parameters) extends XSBundle { 663 val t = Valid(new Bundle { 664 val addr = Output(UInt(2.W)) 665 val tdata = new MatchTriggerIO 666 }) 667 } 668 669class MemTdataDistributeIO(implicit p: Parameters) extends XSBundle { 670 val t = Valid(new Bundle { 671 val addr = Output(UInt(3.W)) 672 val tdata = new MatchTriggerIO 673 }) 674} 675 676class MatchTriggerIO(implicit p: Parameters) extends XSBundle { 677 val matchType = Output(UInt(2.W)) 678 val select = Output(Bool()) 679 val timing = Output(Bool()) 680 val action = Output(Bool()) 681 val chain = Output(Bool()) 682 val tdata2 = Output(UInt(64.W)) 683} 684 685class StallReasonIO(width: Int) extends Bundle { 686 val reason = Output(Vec(width, UInt(log2Ceil(TopDownCounters.NumStallReasons.id).W))) 687 val backReason = Flipped(Valid(UInt(log2Ceil(TopDownCounters.NumStallReasons.id).W))) 688} 689 690// custom l2 - l1 interface 691class L2ToL1Hint(implicit p: Parameters) extends XSBundle with HasDCacheParameters { 692 val sourceId = UInt(log2Up(cfg.nMissEntries).W) // tilelink sourceID -> mshr id 693} 694