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