xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala (revision 887862dbb8debde8ab099befc426493834a69ee7)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState
7import xiangshan.backend.fu.util.CSRConst
8import xiangshan.backend.fu.util.SdtrigExt
9import xiangshan._
10
11class Debug(implicit val p: Parameters) extends Module with HasXSParameter {
12  val io = IO(new DebugIO)
13
14  private val trapInfo        = io.in.trapInfo
15  private val hasTrap         = trapInfo.valid
16  private val trapIsInterrupt = trapInfo.bits.isInterrupt
17  private val intrVec         = trapInfo.bits.intrVec
18  private val trapVec         = trapInfo.bits.trapVec
19  private val singleStep      = trapInfo.bits.singleStep
20  private val trigger         = io.in.trapInfo.bits.trigger
21
22  private val privState = io.in.privState
23  private val debugMode = io.in.debugMode
24
25  private val dcsr = io.in.dcsr
26  private val tcontrol = io.in.tcontrol
27  private val tselect = io.in.tselect
28  private val tdata1Selected = io.in.tdata1Selected
29  private val tdata2Selected = io.in.tdata2Selected
30  private val tdata1Vec = io.in.tdata1Vec
31
32  private val tdata1Update  = io.in.tdata1Update
33  private val tdata2Update  = io.in.tdata2Update
34  private val tdata1Wdata   = io.in.tdata1Wdata
35
36  /**
37   * ways to entry Dmode:
38   *    1. debug intr(from external debug module)
39   *    2. ebreak inst in nonDmode
40   *    3. trigger fire in nonDmode
41   *    4. single step(debug module set dcsr.step before hart resume)
42   */
43  // debug_intr
44  val hasIntr = hasTrap && trapIsInterrupt
45  val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG)
46
47  // debug_exception_ebreak
48  val hasExp = hasTrap && !trapIsInterrupt
49  val breakPoint = trapVec(ExceptionNO.breakPoint).asBool
50  val isEbreak = hasExp && breakPoint && !TriggerAction.isExp(trigger)
51  val ebreakEnterDebugMode =
52    (privState.isModeM && dcsr.EBREAKM.asBool) ||
53      (privState.isModeHS && dcsr.EBREAKS.asBool) ||
54      (privState.isModeHU && dcsr.EBREAKU.asBool) ||
55      (privState.isModeVS && dcsr.EBREAKVS.asBool) ||
56      (privState.isModeVU && dcsr.EBREAKVU.asBool)
57  val hasDebugEbreakException = isEbreak && ebreakEnterDebugMode
58
59  // debug_exception_trigger
60  val mcontrolWireVec = tdata1Vec.map{ mod => {
61    val mcontrolWire = Wire(new Mcontrol)
62    mcontrolWire := mod.DATA.asUInt
63    mcontrolWire
64  }}
65
66  val triggerCanRaiseBpExp = Mux(privState.isModeM, tcontrol.MTE.asBool, true.B)
67  val triggerEnterDebugMode = hasExp && TriggerAction.isDmode(trigger)
68
69  // debug_exception_single
70  val hasSingleStep = hasExp && singleStep
71
72  val hasDebugException = hasDebugEbreakException || triggerEnterDebugMode || hasSingleStep
73  val hasDebugTrap = hasDebugException || hasDebugIntr
74
75  val tselect1H = UIntToOH(tselect.asUInt, TriggerNum).asBools
76  val chainVec = mcontrolWireVec.map(_.CHAIN.asBool)
77  val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b}
78  val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength)
79
80  val triggerUpdate = tdata1Update || tdata2Update
81
82  val mcontrolWdata = Wire(new Mcontrol)
83  mcontrolWdata := tdata1Wdata.DATA.asUInt
84  val tdata1TypeWdata = tdata1Wdata.TYPE
85
86  val mcontrolSelected = Wire(new Mcontrol)
87  mcontrolSelected := tdata1Selected.DATA.asUInt
88
89  val frontendTriggerUpdate =
90    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger ||
91      mcontrolSelected.isFetchTrigger && triggerUpdate
92
93  val memTriggerUpdate =
94    tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger ||
95      mcontrolSelected.isMemAccTrigger && triggerUpdate
96
97  val triggerEnableVec = tdata1Vec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) =>
98    tdata1.TYPE.isLegal && (
99      mcontrol.M && privState.isModeM  ||
100        mcontrol.S && privState.isModeHS ||
101        mcontrol.U && privState.isModeHU)
102  }
103
104  val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
105    case (tEnable, mod) => tEnable && mod.isFetchTrigger
106  }
107  val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map {
108    case (tEnable, mod) => tEnable && mod.isMemAccTrigger
109  }
110
111  io.out.frontendTrigger.tUpdate.valid        := RegNext(RegNext(frontendTriggerUpdate))
112  io.out.frontendTrigger.tUpdate.bits.addr    := tselect.asUInt
113  io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
114  io.out.frontendTrigger.tEnableVec           := fetchTriggerEnableVec
115  io.out.frontendTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp
116  io.out.frontendTrigger.debugMode            := debugMode
117
118  io.out.memTrigger.tUpdate.valid            := RegNext(RegNext(memTriggerUpdate))
119  io.out.memTrigger.tUpdate.bits.addr        := tselect.asUInt
120  io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected)
121  io.out.memTrigger.tEnableVec               := memAccTriggerEnableVec
122  io.out.memTrigger.triggerCanRaiseBpExp     := triggerCanRaiseBpExp
123  io.out.memTrigger.debugMode                := debugMode
124
125  io.out.triggerFrontendChange  := frontendTriggerUpdate
126  io.out.newTriggerChainIsLegal := newTriggerChainIsLegal
127
128  io.out.hasDebugTrap            := hasDebugTrap
129  io.out.hasDebugIntr            := hasDebugIntr
130  io.out.hasSingleStep           := hasSingleStep
131  io.out.triggerEnterDebugMode   := triggerEnterDebugMode
132  io.out.hasDebugEbreakException := hasDebugEbreakException
133  io.out.breakPoint              := breakPoint
134}
135
136class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter {
137  val in = Input(new Bundle {
138    val trapInfo = ValidIO(new Bundle {
139      val trapVec = UInt(64.W)
140      val intrVec = UInt(64.W)
141      val isInterrupt = Bool()
142      val singleStep = Bool()
143      val trigger = TriggerAction()
144    })
145
146    val privState = new PrivState
147    val debugMode = Bool()
148
149    val dcsr = new DcsrBundle
150    val tcontrol = new TcontrolBundle
151    val tselect = new TselectBundle(TriggerNum)
152    val tdata1Selected = new Tdata1Bundle
153    val tdata2Selected = new Tdata2Bundle
154    val tdata1Vec = Vec(TriggerNum, new Tdata1Bundle)
155
156    val tdata1Update = Bool()
157    val tdata2Update = Bool()
158    val tdata1Wdata = new Tdata1Bundle
159  })
160
161  val out = Output(new Bundle{
162    // trigger
163    val triggerFrontendChange = Bool()
164    val newTriggerChainIsLegal = Bool()
165    val memTrigger = new MemTdataDistributeIO()
166    val frontendTrigger = new FrontendTdataDistributeIO()
167
168    val hasDebugTrap = Bool()
169    val hasDebugIntr = Bool()
170    val hasSingleStep = Bool()
171    val triggerEnterDebugMode = Bool()
172    val hasDebugEbreakException = Bool()
173    val breakPoint = Bool()
174  })
175}
176
177class CsrTriggerBundle(implicit val p: Parameters) extends Bundle with HasXSParameter {
178  val tdataVec = Vec(TriggerNum, new MatchTriggerIO)
179  val tEnableVec = Vec(TriggerNum, Bool())
180  val debugMode = Bool()
181  val triggerCanRaiseBpExp = Bool()
182}
183class StoreTrigger(implicit val p: Parameters) extends Module with HasXSParameter with SdtrigExt {
184  val io = IO(new Bundle(){
185    val fromCsrTrigger = Input(new CsrTriggerBundle)
186
187    val fromStore = Input(new Bundle {
188      val vaddr = UInt(VAddrBits.W)
189    })
190
191    val toStore = Output(new Bundle{
192      val triggerAction = TriggerAction()
193    })
194  })
195  val tdataVec      = io.fromCsrTrigger.tdataVec
196  val tEnableVec    = io.fromCsrTrigger.tEnableVec
197  val triggerCanRaiseBpExp = io.fromCsrTrigger.triggerCanRaiseBpExp
198  val debugMode = io.fromCsrTrigger.debugMode
199  val vaddr = io.fromStore.vaddr
200
201  val triggerTimingVec = VecInit(tdataVec.map(_.timing))
202  val triggerChainVec = VecInit(tdataVec.map(_.chain))
203
204  val triggerHitVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B)))
205  val triggerCanFireVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B)))
206
207  // Trigger can't hit/fire in debug mode.
208  for (i <- 0 until TriggerNum) {
209    triggerHitVec(i) := !tdataVec(i).select && !debugMode && TriggerCmp(
210      vaddr,
211      tdataVec(i).tdata2,
212      tdataVec(i).matchType,
213      tEnableVec(i) && tdataVec(i).store
214    )
215  }
216  TriggerCheckCanFire(TriggerNum, triggerCanFireVec, triggerHitVec, triggerTimingVec, triggerChainVec)
217
218  val actionVec = VecInit(tdataVec.map(_.action))
219  val triggerAction = Wire(TriggerAction())
220  TriggerUtil.triggerActionGen(triggerAction, triggerCanFireVec, actionVec, triggerCanRaiseBpExp)
221
222  io.toStore.triggerAction := triggerAction
223}