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