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