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