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 utils._ 35 36import scala.math.max 37import Chisel.experimental.chiselName 38import chipsalliance.rocketchip.config.Parameters 39import chisel3.util.BitPat.bitPatToUInt 40import xiangshan.backend.exu.ExuConfig 41import xiangshan.backend.fu.PMPEntry 42import xiangshan.frontend.Ftq_Redirect_SRAMEntry 43import xiangshan.frontend.AllFoldedHistories 44import xiangshan.frontend.AllAheadFoldedHistoryOldestBits 45 46class ValidUndirectioned[T <: Data](gen: T) extends Bundle { 47 val valid = Bool() 48 val bits = gen.cloneType.asInstanceOf[T] 49 50} 51 52object ValidUndirectioned { 53 def apply[T <: Data](gen: T) = { 54 new ValidUndirectioned[T](gen) 55 } 56} 57 58object RSFeedbackType { 59 val tlbMiss = 0.U(3.W) 60 val mshrFull = 1.U(3.W) 61 val dataInvalid = 2.U(3.W) 62 val bankConflict = 3.U(3.W) 63 val ldVioCheckRedo = 4.U(3.W) 64 65 val feedbackInvalid = 7.U(3.W) 66 67 def apply() = UInt(3.W) 68} 69 70class PredictorAnswer(implicit p: Parameters) extends XSBundle { 71 val hit = if (!env.FPGAPlatform) Bool() else UInt(0.W) 72 val taken = if (!env.FPGAPlatform) Bool() else UInt(0.W) 73 val target = if (!env.FPGAPlatform) UInt(VAddrBits.W) else UInt(0.W) 74} 75 76class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParameter { 77 // from backend 78 val pc = UInt(VAddrBits.W) 79 // frontend -> backend -> frontend 80 val pd = new PreDecodeInfo 81 val rasSp = UInt(log2Up(RasSize).W) 82 val rasEntry = new RASEntry 83 // val hist = new ShiftingGlobalHistory 84 val folded_hist = new AllFoldedHistories(foldedGHistInfos) 85 val afhob = new AllAheadFoldedHistoryOldestBits(foldedGHistInfos) 86 val lastBrNumOH = UInt((numBr+1).W) 87 val ghr = UInt(UbtbGHRLength.W) 88 val histPtr = new CGHPtr 89 val specCnt = Vec(numBr, UInt(10.W)) 90 // need pipeline update 91 val br_hit = Bool() 92 val predTaken = Bool() 93 val target = UInt(VAddrBits.W) 94 val taken = Bool() 95 val isMisPred = Bool() 96 val shift = UInt((log2Ceil(numBr)+1).W) 97 val addIntoHist = Bool() 98 99 def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = { 100 // this.hist := entry.ghist 101 this.folded_hist := entry.folded_hist 102 this.lastBrNumOH := entry.lastBrNumOH 103 this.afhob := entry.afhob 104 this.histPtr := entry.histPtr 105 this.rasSp := entry.rasSp 106 this.rasEntry := entry.rasTop 107 this 108 } 109} 110 111// Dequeue DecodeWidth insts from Ibuffer 112class CtrlFlow(implicit p: Parameters) extends XSBundle { 113 val instr = UInt(32.W) 114 val pc = UInt(VAddrBits.W) 115 val foldpc = UInt(MemPredPCWidth.W) 116 val exceptionVec = ExceptionVec() 117 val trigger = new TriggerCf 118 val pd = new PreDecodeInfo 119 val pred_taken = Bool() 120 val crossPageIPFFix = Bool() 121 val storeSetHit = Bool() // inst has been allocated an store set 122 val waitForRobIdx = new RobPtr // store set predicted previous store robIdx 123 // Load wait is needed 124 // load inst will not be executed until former store (predicted by mdp) addr calcuated 125 val loadWaitBit = Bool() 126 // If (loadWaitBit && loadWaitStrict), strict load wait is needed 127 // load inst will not be executed until ALL former store addr calcuated 128 val loadWaitStrict = Bool() 129 val ssid = UInt(SSIDWidth.W) 130 val ftqPtr = new FtqPtr 131 val ftqOffset = UInt(log2Up(PredictWidth).W) 132 // This inst will flush all the pipe when it is the oldest inst in ROB, 133 // then replay from this inst itself 134 val replayInst = Bool() 135} 136 137 138class FPUCtrlSignals(implicit p: Parameters) extends XSBundle { 139 val isAddSub = Bool() // swap23 140 val typeTagIn = UInt(1.W) 141 val typeTagOut = UInt(1.W) 142 val fromInt = Bool() 143 val wflags = Bool() 144 val fpWen = Bool() 145 val fmaCmd = UInt(2.W) 146 val div = Bool() 147 val sqrt = Bool() 148 val fcvt = Bool() 149 val typ = UInt(2.W) 150 val fmt = UInt(2.W) 151 val ren3 = Bool() //TODO: remove SrcType.fp 152 val rm = UInt(3.W) 153} 154 155// Decode DecodeWidth insts at Decode Stage 156class CtrlSignals(implicit p: Parameters) extends XSBundle { 157 val srcType = Vec(3, SrcType()) 158 val lsrc = Vec(3, UInt(5.W)) 159 val ldest = UInt(5.W) 160 val fuType = FuType() 161 val fuOpType = FuOpType() 162 val rfWen = Bool() 163 val fpWen = Bool() 164 val isXSTrap = Bool() 165 val noSpecExec = Bool() // wait forward 166 val blockBackward = Bool() // block backward 167 val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit 168 val selImm = SelImm() 169 val imm = UInt(ImmUnion.maxLen.W) 170 val commitType = CommitType() 171 val fpu = new FPUCtrlSignals 172 val isMove = Bool() 173 val singleStep = Bool() 174 // This inst will flush all the pipe when it is the oldest inst in ROB, 175 // then replay from this inst itself 176 val replayInst = Bool() 177 178 private def allSignals = srcType ++ Seq(fuType, fuOpType, rfWen, fpWen, 179 isXSTrap, noSpecExec, blockBackward, flushPipe, selImm) 180 181 def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]): CtrlSignals = { 182 val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decodeDefault, table) 183 allSignals zip decoder foreach { case (s, d) => s := d } 184 commitType := DontCare 185 this 186 } 187 188 def decode(bit: List[BitPat]): CtrlSignals = { 189 allSignals.zip(bit.map(bitPatToUInt(_))).foreach{ case (s, d) => s := d } 190 this 191 } 192 193 def isWFI: Bool = fuType === FuType.csr && fuOpType === CSROpType.wfi 194 def isSoftPrefetch: Bool = { 195 fuType === FuType.alu && fuOpType === ALUOpType.or && selImm === SelImm.IMM_I && ldest === 0.U 196 } 197} 198 199class CfCtrl(implicit p: Parameters) extends XSBundle { 200 val cf = new CtrlFlow 201 val ctrl = new CtrlSignals 202} 203 204class PerfDebugInfo(implicit p: Parameters) extends XSBundle { 205 val eliminatedMove = Bool() 206 // val fetchTime = UInt(64.W) 207 val renameTime = UInt(XLEN.W) 208 val dispatchTime = UInt(XLEN.W) 209 val enqRsTime = UInt(XLEN.W) 210 val selectTime = UInt(XLEN.W) 211 val issueTime = UInt(XLEN.W) 212 val writebackTime = UInt(XLEN.W) 213 // val commitTime = UInt(64.W) 214 val runahead_checkpoint_id = UInt(64.W) 215} 216 217// Separate LSQ 218class LSIdx(implicit p: Parameters) extends XSBundle { 219 val lqIdx = new LqPtr 220 val sqIdx = new SqPtr 221} 222 223// CfCtrl -> MicroOp at Rename Stage 224class MicroOp(implicit p: Parameters) extends CfCtrl { 225 val srcState = Vec(3, SrcState()) 226 val psrc = Vec(3, UInt(PhyRegIdxWidth.W)) 227 val pdest = UInt(PhyRegIdxWidth.W) 228 val old_pdest = UInt(PhyRegIdxWidth.W) 229 val robIdx = new RobPtr 230 val lqIdx = new LqPtr 231 val sqIdx = new SqPtr 232 val eliminatedMove = Bool() 233 val debugInfo = new PerfDebugInfo 234 def needRfRPort(index: Int, isFp: Boolean, ignoreState: Boolean = true) : Bool = { 235 val stateReady = srcState(index) === SrcState.rdy || ignoreState.B 236 val readReg = if (isFp) { 237 ctrl.srcType(index) === SrcType.fp 238 } else { 239 ctrl.srcType(index) === SrcType.reg && ctrl.lsrc(index) =/= 0.U 240 } 241 readReg && stateReady 242 } 243 def srcIsReady: Vec[Bool] = { 244 VecInit(ctrl.srcType.zip(srcState).map{ case (t, s) => SrcType.isPcOrImm(t) || s === SrcState.rdy }) 245 } 246 def clearExceptions( 247 exceptionBits: Seq[Int] = Seq(), 248 flushPipe: Boolean = false, 249 replayInst: Boolean = false 250 ): MicroOp = { 251 cf.exceptionVec.zipWithIndex.filterNot(x => exceptionBits.contains(x._2)).foreach(_._1 := false.B) 252 if (!flushPipe) { ctrl.flushPipe := false.B } 253 if (!replayInst) { ctrl.replayInst := false.B } 254 this 255 } 256 // Assume only the LUI instruction is decoded with IMM_U in ALU. 257 def isLUI: Bool = ctrl.selImm === SelImm.IMM_U && ctrl.fuType === FuType.alu 258 // This MicroOp is used to wakeup another uop (the successor: (psrc, srcType). 259 def wakeup(successor: Seq[(UInt, UInt)], exuCfg: ExuConfig): Seq[(Bool, Bool)] = { 260 successor.map{ case (src, srcType) => 261 val pdestMatch = pdest === src 262 // For state: no need to check whether src is x0/imm/pc because they are always ready. 263 val rfStateMatch = if (exuCfg.readIntRf) ctrl.rfWen else false.B 264 val fpMatch = if (exuCfg.readFpRf) ctrl.fpWen else false.B 265 val bothIntFp = exuCfg.readIntRf && exuCfg.readFpRf 266 val bothStateMatch = Mux(SrcType.regIsFp(srcType), fpMatch, rfStateMatch) 267 val stateCond = pdestMatch && (if (bothIntFp) bothStateMatch else rfStateMatch || fpMatch) 268 // For data: types are matched and int pdest is not $zero. 269 val rfDataMatch = if (exuCfg.readIntRf) ctrl.rfWen && src =/= 0.U else false.B 270 val dataCond = pdestMatch && (rfDataMatch && SrcType.isReg(srcType) || fpMatch && SrcType.isFp(srcType)) 271 (stateCond, dataCond) 272 } 273 } 274 // This MicroOp is used to wakeup another uop (the successor: MicroOp). 275 def wakeup(successor: MicroOp, exuCfg: ExuConfig): Seq[(Bool, Bool)] = { 276 wakeup(successor.psrc.zip(successor.ctrl.srcType), exuCfg) 277 } 278 def isJump: Bool = FuType.isJumpExu(ctrl.fuType) 279} 280 281class XSBundleWithMicroOp(implicit p: Parameters) extends XSBundle { 282 val uop = new MicroOp 283} 284 285class MicroOpRbExt(implicit p: Parameters) extends XSBundleWithMicroOp { 286 val flag = UInt(1.W) 287} 288 289class Redirect(implicit p: Parameters) extends XSBundle { 290 val robIdx = new RobPtr 291 val ftqIdx = new FtqPtr 292 val ftqOffset = UInt(log2Up(PredictWidth).W) 293 val level = RedirectLevel() 294 val interrupt = Bool() 295 val cfiUpdate = new CfiUpdateInfo 296 297 val stFtqIdx = new FtqPtr // for load violation predict 298 val stFtqOffset = UInt(log2Up(PredictWidth).W) 299 300 val debug_runahead_checkpoint_id = UInt(64.W) 301 302 // def isUnconditional() = RedirectLevel.isUnconditional(level) 303 def flushItself() = RedirectLevel.flushItself(level) 304 // def isException() = RedirectLevel.isException(level) 305} 306 307class Dp1ToDp2IO(implicit p: Parameters) extends XSBundle { 308 val intDqToDp2 = Vec(dpParams.IntDqDeqWidth, DecoupledIO(new MicroOp)) 309 val fpDqToDp2 = Vec(dpParams.FpDqDeqWidth, DecoupledIO(new MicroOp)) 310 val lsDqToDp2 = Vec(dpParams.LsDqDeqWidth, DecoupledIO(new MicroOp)) 311} 312 313class ResetPregStateReq(implicit p: Parameters) extends XSBundle { 314 // NOTE: set isInt and isFp both to 'false' when invalid 315 val isInt = Bool() 316 val isFp = Bool() 317 val preg = UInt(PhyRegIdxWidth.W) 318} 319 320class DebugBundle(implicit p: Parameters) extends XSBundle { 321 val isMMIO = Bool() 322 val isPerfCnt = Bool() 323 val paddr = UInt(PAddrBits.W) 324 val vaddr = UInt(VAddrBits.W) 325} 326 327class ExuInput(implicit p: Parameters) extends XSBundleWithMicroOp { 328 val src = Vec(3, UInt(XLEN.W)) 329} 330 331class ExuOutput(implicit p: Parameters) extends XSBundleWithMicroOp { 332 val data = UInt(XLEN.W) 333 val fflags = UInt(5.W) 334 val redirectValid = Bool() 335 val redirect = new Redirect 336 val debug = new DebugBundle 337} 338 339class ExternalInterruptIO(implicit p: Parameters) extends XSBundle { 340 val mtip = Input(Bool()) 341 val msip = Input(Bool()) 342 val meip = Input(Bool()) 343 val seip = Input(Bool()) 344 val debug = Input(Bool()) 345} 346 347class CSRSpecialIO(implicit p: Parameters) extends XSBundle { 348 val exception = Flipped(ValidIO(new MicroOp)) 349 val isInterrupt = Input(Bool()) 350 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 351 val trapTarget = Output(UInt(VAddrBits.W)) 352 val externalInterrupt = new ExternalInterruptIO 353 val interrupt = Output(Bool()) 354} 355 356class ExceptionInfo(implicit p: Parameters) extends XSBundleWithMicroOp { 357 val isInterrupt = Bool() 358} 359 360class RobCommitInfo(implicit p: Parameters) extends XSBundle { 361 val ldest = UInt(5.W) 362 val rfWen = Bool() 363 val fpWen = Bool() 364 val wflags = Bool() 365 val commitType = CommitType() 366 val pdest = UInt(PhyRegIdxWidth.W) 367 val old_pdest = UInt(PhyRegIdxWidth.W) 368 val ftqIdx = new FtqPtr 369 val ftqOffset = UInt(log2Up(PredictWidth).W) 370 val isMove = Bool() 371 372 // these should be optimized for synthesis verilog 373 val pc = UInt(VAddrBits.W) 374} 375 376class RobCommitIO(implicit p: Parameters) extends XSBundle { 377 val isCommit = Bool() 378 val commitValid = Vec(CommitWidth, Bool()) 379 380 val isWalk = Bool() 381 // valid bits optimized for walk 382 val walkValid = Vec(CommitWidth, Bool()) 383 384 val info = Vec(CommitWidth, new RobCommitInfo) 385 386 def hasWalkInstr: Bool = isWalk && walkValid.asUInt.orR 387 def hasCommitInstr: Bool = isCommit && commitValid.asUInt.orR 388} 389 390class RSFeedback(implicit p: Parameters) extends XSBundle { 391 val rsIdx = UInt(log2Up(IssQueSize).W) 392 val hit = Bool() 393 val flushState = Bool() 394 val sourceType = RSFeedbackType() 395 val dataInvalidSqIdx = new SqPtr 396} 397 398class MemRSFeedbackIO(implicit p: Parameters) extends XSBundle { 399 // Note: you need to update in implicit Parameters p before imp MemRSFeedbackIO 400 // for instance: MemRSFeedbackIO()(updateP) 401 val feedbackSlow = ValidIO(new RSFeedback()) // dcache miss queue full, dtlb miss 402 val feedbackFast = ValidIO(new RSFeedback()) // bank conflict 403 val rsIdx = Input(UInt(log2Up(IssQueSize).W)) 404 val isFirstIssue = Input(Bool()) 405} 406 407class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle { 408 // to backend end 409 val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) 410 val fromFtq = new FtqToCtrlIO 411 // from backend 412 val toFtq = Flipped(new CtrlToFtqIO) 413} 414 415class SatpStruct(implicit p: Parameters) extends XSBundle { 416 val mode = UInt(4.W) 417 val asid = UInt(16.W) 418 val ppn = UInt(44.W) 419} 420 421class TlbSatpBundle(implicit p: Parameters) extends SatpStruct { 422 val changed = Bool() 423 424 def apply(satp_value: UInt): Unit = { 425 require(satp_value.getWidth == XLEN) 426 val sa = satp_value.asTypeOf(new SatpStruct) 427 mode := sa.mode 428 asid := sa.asid 429 ppn := Cat(0.U(44-PAddrBits), sa.ppn(PAddrBits-1, 0)).asUInt() 430 changed := DataChanged(sa.asid) // when ppn is changed, software need do the flush 431 } 432} 433 434class TlbCsrBundle(implicit p: Parameters) extends XSBundle { 435 val satp = new TlbSatpBundle() 436 val priv = new Bundle { 437 val mxr = Bool() 438 val sum = Bool() 439 val imode = UInt(2.W) 440 val dmode = UInt(2.W) 441 } 442 443 override def toPrintable: Printable = { 444 p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " + 445 p"Priv mxr:${priv.mxr} sum:${priv.sum} imode:${priv.imode} dmode:${priv.dmode}" 446 } 447} 448 449class SfenceBundle(implicit p: Parameters) extends XSBundle { 450 val valid = Bool() 451 val bits = new Bundle { 452 val rs1 = Bool() 453 val rs2 = Bool() 454 val addr = UInt(VAddrBits.W) 455 val asid = UInt(AsidLength.W) 456 val flushPipe = Bool() 457 } 458 459 override def toPrintable: Printable = { 460 p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}, flushPipe:${bits.flushPipe}" 461 } 462} 463 464// Bundle for load violation predictor updating 465class MemPredUpdateReq(implicit p: Parameters) extends XSBundle { 466 val valid = Bool() 467 468 // wait table update 469 val waddr = UInt(MemPredPCWidth.W) 470 val wdata = Bool() // true.B by default 471 472 // store set update 473 // by default, ldpc/stpc should be xor folded 474 val ldpc = UInt(MemPredPCWidth.W) 475 val stpc = UInt(MemPredPCWidth.W) 476} 477 478class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle { 479 // Prefetcher 480 val l1I_pf_enable = Output(Bool()) 481 val l2_pf_enable = Output(Bool()) 482 // ICache 483 val icache_parity_enable = Output(Bool()) 484 // Labeled XiangShan 485 val dsid = Output(UInt(8.W)) // TODO: DsidWidth as parameter 486 // Load violation predictor 487 val lvpred_disable = Output(Bool()) 488 val no_spec_load = Output(Bool()) 489 val storeset_wait_store = Output(Bool()) 490 val storeset_no_fast_wakeup = Output(Bool()) 491 val lvpred_timeout = Output(UInt(5.W)) 492 // Branch predictor 493 val bp_ctrl = Output(new BPUCtrl) 494 // Memory Block 495 val sbuffer_threshold = Output(UInt(4.W)) 496 val ldld_vio_check_enable = Output(Bool()) 497 val soft_prefetch_enable = Output(Bool()) 498 val cache_error_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