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