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