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