xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala (revision 39ec22f641d646c7405140ce0a8319ae2f29e06d)
1223cba9dSXuan Hupackage xiangshan.backend.fu.NewCSR
2223cba9dSXuan Hu
3a7a6d0a6Schengguanghuiimport freechips.rocketchip.devices.debug.DebugModuleKey
4a7a6d0a6Schengguanghuiimport org.chipsalliance.cde.config.Parameters
5657432e4Schengguanghuiimport freechips.rocketchip.rocket.CSRs
6223cba9dSXuan Huimport chisel3._
7223cba9dSXuan Huimport chisel3.util._
8a7a6d0a6Schengguanghuiimport utils.ConsecutiveOnes
9223cba9dSXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines._
10223cba9dSXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.{
11223cba9dSXuan Hu  CSRWARLField => WARL,
12223cba9dSXuan Hu  CSRRWField => RW,
13223cba9dSXuan Hu  CSRROField => RO,
14223cba9dSXuan Hu}
15223cba9dSXuan Huimport xiangshan.backend.fu.NewCSR.CSRFunc._
16a7a6d0a6Schengguanghuiimport xiangshan.backend.fu.NewCSR.CSREvents._
17499d09b3SsinceforYyimport xiangshan.backend.fu.NewCSR.CSRBundles._
18a7a6d0a6Schengguanghuiimport CSRConfig._
190f9a14c6Schengguanghuiimport utility.SignExt
207e0f64b0SGuanghui Chengimport xiangshan.TriggerAction
217e0f64b0SGuanghui Cheng
22223cba9dSXuan Huimport scala.collection.immutable.SeqMap
23223cba9dSXuan Hu
24a7a6d0a6Schengguanghui
25223cba9dSXuan Hutrait DebugLevel { self: NewCSR =>
26afc7cd8cSXuan Hu  val tselect = Module(new CSRModule("Tselect", new TselectBundle(TriggerNum)) {
27afc7cd8cSXuan Hu    when (this.w.wen && this.w.wdata < TriggerNum.U) {
28afc7cd8cSXuan Hu      reg := this.w.wdata
29afc7cd8cSXuan Hu    }.otherwise {
30afc7cd8cSXuan Hu      reg := reg
31afc7cd8cSXuan Hu    }
32afc7cd8cSXuan Hu  })
33657432e4Schengguanghui    .setAddr(CSRs.tselect)
341d72599bSsinceforYy
35a7a6d0a6Schengguanghui  val tdata1 = Module(new CSRModule("Tdata1") with HasTdataSink {
36b51a1abdSchengguanghui    regOut := tdataRead.tdata1
37a7a6d0a6Schengguanghui  })
38657432e4Schengguanghui    .setAddr(CSRs.tdata1)
391d72599bSsinceforYy
40a7a6d0a6Schengguanghui  val tdata2 = Module(new CSRModule("Tdata2") with HasTdataSink {
41b51a1abdSchengguanghui    regOut := tdataRead.tdata2
42a7a6d0a6Schengguanghui  })
43657432e4Schengguanghui    .setAddr(CSRs.tdata2)
44a7a6d0a6Schengguanghui
45a7a6d0a6Schengguanghui  val tdata1RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i =>
46*39ec22f6SGuanghui Cheng    Module(new CSRModule(s"Trigger$i" + s"_Tdata1", new Tdata1Bundle) with HasTriggerBundle {
47a7a6d0a6Schengguanghui      when(wen){
48*39ec22f6SGuanghui Cheng        reg := wdata.writeTdata1(canWriteDmode, chainable).asUInt
49a7a6d0a6Schengguanghui      }
50a7a6d0a6Schengguanghui    })
51a7a6d0a6Schengguanghui  )
52a7a6d0a6Schengguanghui  val tdata2RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i =>
53a7a6d0a6Schengguanghui    Module(new CSRModule(s"Trigger$i" + s"_Tdata2", new Tdata2Bundle))
54a7a6d0a6Schengguanghui  )
55a7a6d0a6Schengguanghui
56a7a6d0a6Schengguanghui  val tinfo = Module(new CSRModule("Tinfo", new TinfoBundle))
57657432e4Schengguanghui    .setAddr(CSRs.tinfo)
58657432e4Schengguanghui
59a751b11aSchengguanghui  val dcsr = Module(new CSRModule("Dcsr", new DcsrBundle) with TrapEntryDEventSinkBundle with DretEventSinkBundle with HasNmipBundle {
60a751b11aSchengguanghui    when(nmip){
61a751b11aSchengguanghui      reg.NMIP := nmip
62a751b11aSchengguanghui    }
63a751b11aSchengguanghui  })
64657432e4Schengguanghui    .setAddr(CSRs.dcsr)
65223cba9dSXuan Hu
663e8a0170SXuan Hu  val dpc = Module(new CSRModule("Dpc", new Epc) with TrapEntryDEventSinkBundle)
67657432e4Schengguanghui    .setAddr(CSRs.dpc)
68223cba9dSXuan Hu
69a7a6d0a6Schengguanghui  val dscratch0 = Module(new CSRModule("Dscratch0", new DscratchBundle))
70657432e4Schengguanghui    .setAddr(CSRs.dscratch0)
71223cba9dSXuan Hu
72a7a6d0a6Schengguanghui  val dscratch1 = Module(new CSRModule("Dscratch1", new DscratchBundle))
73657432e4Schengguanghui    .setAddr(CSRs.dscratch1)
74223cba9dSXuan Hu
75223cba9dSXuan Hu  val debugCSRMods = Seq(
761d72599bSsinceforYy    tdata1,
77a7a6d0a6Schengguanghui    tdata2,
78a7a6d0a6Schengguanghui    tselect,
79a7a6d0a6Schengguanghui    tinfo,
80223cba9dSXuan Hu    dcsr,
81223cba9dSXuan Hu    dpc,
82223cba9dSXuan Hu    dscratch0,
83223cba9dSXuan Hu    dscratch1,
84223cba9dSXuan Hu  )
85223cba9dSXuan Hu
86223cba9dSXuan Hu  val debugCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_ <: CSRBundle], UInt)] = SeqMap.from(
878aa89407SXuan Hu    debugCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata)).iterator
88223cba9dSXuan Hu  )
89223cba9dSXuan Hu
90223cba9dSXuan Hu  val debugCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
91223cba9dSXuan Hu    debugCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator
92223cba9dSXuan Hu  )
93a7a6d0a6Schengguanghui
94a7a6d0a6Schengguanghui  private val tdata1Rdata = Mux1H(
95a7a6d0a6Schengguanghui    tdata1RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata}
96a7a6d0a6Schengguanghui  )
97a7a6d0a6Schengguanghui
98a7a6d0a6Schengguanghui  private val tdata2Rdata = Mux1H(
99a7a6d0a6Schengguanghui    tdata2RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata}
100a7a6d0a6Schengguanghui  )
101a7a6d0a6Schengguanghui
102a7a6d0a6Schengguanghui  debugCSRMods.foreach { mod =>
103a7a6d0a6Schengguanghui    mod match {
104a7a6d0a6Schengguanghui      case m: HasTdataSink =>
105a7a6d0a6Schengguanghui        m.tdataRead.tdata1 := tdata1Rdata
106a7a6d0a6Schengguanghui        m.tdataRead.tdata2 := tdata2Rdata
107a7a6d0a6Schengguanghui      case _ =>
108a7a6d0a6Schengguanghui    }
109223cba9dSXuan Hu  }
110223cba9dSXuan Hu
111a7a6d0a6Schengguanghui}
112a7a6d0a6Schengguanghui
113a7a6d0a6Schengguanghui// tselect
114a7a6d0a6Schengguanghuiclass TselectBundle(triggerNum: Int) extends CSRBundle{
115a7a6d0a6Schengguanghui  override val len: Int = log2Up(triggerNum)
116499d09b3SsinceforYy  val ALL = WARL(len - 1, 0, wNoEffectWhen(WriteTselect)).withReset(0.U)
117a7a6d0a6Schengguanghui  def WriteTselect(wdata: UInt) = {
118a7a6d0a6Schengguanghui    wdata >= triggerNum.U
119a7a6d0a6Schengguanghui  }
120a7a6d0a6Schengguanghui}
121a7a6d0a6Schengguanghui
122a7a6d0a6Schengguanghui// tdata1
1231d72599bSsinceforYyclass Tdata1Bundle extends CSRBundle{
1241d72599bSsinceforYy  val TYPE    = Tdata1Type(63, 60, wNoFilter).withReset(Tdata1Type.Disabled)
125a7a6d0a6Schengguanghui  val DMODE   = RW(59).withReset(0.U)
126499d09b3SsinceforYy  val DATA    = RW(58, 0).withReset(0.U)
127a7a6d0a6Schengguanghui
128a7a6d0a6Schengguanghui  def getTriggerAction: CSREnumType = {
129cc6e4cb5Schengguanghui    val res = Wire(new Mcontrol6)
130a7a6d0a6Schengguanghui    res := this.asUInt
131a7a6d0a6Schengguanghui    res.ACTION
1321d72599bSsinceforYy  }
1331d72599bSsinceforYy
134*39ec22f6SGuanghui Cheng  def writeTdata1(canWriteDmode: Bool, chainable: Bool): Tdata1Bundle = {
135a7a6d0a6Schengguanghui    val res = Wire(new Tdata1Bundle)
136a7a6d0a6Schengguanghui    res := this.asUInt
137*39ec22f6SGuanghui Cheng    val dmode = this.DMODE.asBool && canWriteDmode
138a7a6d0a6Schengguanghui    res.TYPE := this.TYPE.legalize.asUInt
139a7a6d0a6Schengguanghui    res.DMODE := dmode
140a7a6d0a6Schengguanghui    when(this.TYPE.isLegal) {
141cc6e4cb5Schengguanghui      val mcontrol6Res = Wire(new Mcontrol6)
142cc6e4cb5Schengguanghui      mcontrol6Res := this.DATA.asUInt
143cc6e4cb5Schengguanghui      res.DATA := mcontrol6Res.writeData(dmode, chainable).asUInt
144a7a6d0a6Schengguanghui    }.otherwise{
145a7a6d0a6Schengguanghui      res.DATA := 0.U
146a7a6d0a6Schengguanghui    }
147a7a6d0a6Schengguanghui   res
148a7a6d0a6Schengguanghui  }
149a7a6d0a6Schengguanghui}
150a7a6d0a6Schengguanghui
151cc6e4cb5Schengguanghuiclass Mcontrol6 extends CSRBundle{
152a7a6d0a6Schengguanghui  override val len: Int = 59
153a7a6d0a6Schengguanghui  // xiangshan don't support match = NAPOT
154cc6e4cb5Schengguanghui  val UNCERTAIN   = RO(26).withReset(0.U)
155cc6e4cb5Schengguanghui  val HIT1        = RO(25).withReset(0.U)
156cc6e4cb5Schengguanghui  val VS          = RW(24).withReset(0.U)
157cc6e4cb5Schengguanghui  val VU          = RW(23).withReset(0.U)
158cc6e4cb5Schengguanghui  val HIT0        = RO(22).withReset(0.U)
159c08f49a0Schengguanghui  val SELECT      = RO(21).withReset(0.U)
160c08f49a0Schengguanghui  val SIZE        = RO(18, 16).withReset(0.U)
161a7a6d0a6Schengguanghui  val ACTION      = TrigAction(15, 12, wNoFilter).withReset(TrigAction.BreakpointExp)
162a7a6d0a6Schengguanghui  val CHAIN       = RW(11).withReset(0.U)
163a7a6d0a6Schengguanghui  val MATCH       = TrigMatch(10, 7, wNoFilter).withReset(TrigMatch.EQ)
164a7a6d0a6Schengguanghui  val M           = RW(6).withReset(0.U)
165cc6e4cb5Schengguanghui  val UNCERTAINEN = RO(5).withReset(0.U)
166a7a6d0a6Schengguanghui  val S           = RW(4).withReset(0.U)
167a7a6d0a6Schengguanghui  val U           = RW(3).withReset(0.U)
168a7a6d0a6Schengguanghui  val EXECUTE     = RW(2).withReset(0.U)
169a7a6d0a6Schengguanghui  val STORE       = RW(1).withReset(0.U)
170a7a6d0a6Schengguanghui  val LOAD        = RW(0).withReset(0.U)
171a7a6d0a6Schengguanghui
172cc6e4cb5Schengguanghui  def writeData(dmode: Bool, chainable: Bool): Mcontrol6 = {
173cc6e4cb5Schengguanghui    val res = Wire(new Mcontrol6)
174a7a6d0a6Schengguanghui    res := this.asUInt
175c08f49a0Schengguanghui    res.UNCERTAIN   := 0.U
176c08f49a0Schengguanghui    res.HIT1        := 0.U
177c08f49a0Schengguanghui    res.HIT0        := 0.U
178c08f49a0Schengguanghui    res.SELECT      := 0.U
179cc6e4cb5Schengguanghui    res.SIZE        := 0.U
180a7a6d0a6Schengguanghui    res.ACTION      := this.ACTION.legalize(dmode).asUInt
181a7a6d0a6Schengguanghui    res.CHAIN       := this.CHAIN.asBool && chainable
182a7a6d0a6Schengguanghui    res.MATCH       := this.MATCH.legalize.asUInt
183c08f49a0Schengguanghui    res.UNCERTAINEN := 0.U
184a7a6d0a6Schengguanghui    res
185a7a6d0a6Schengguanghui  }
186a7a6d0a6Schengguanghui  def isFetchTrigger: Bool = this.EXECUTE.asBool
187a7a6d0a6Schengguanghui  def isMemAccTrigger: Bool = this.STORE || this.LOAD
188a7a6d0a6Schengguanghui}
189a7a6d0a6Schengguanghui
190a7a6d0a6Schengguanghui
191a7a6d0a6Schengguanghuiobject Tdata1Type extends CSREnum with WARLApply {
192a7a6d0a6Schengguanghui  val None         = Value(0.U)
193a7a6d0a6Schengguanghui  val Legacy       = Value(1.U)
194a7a6d0a6Schengguanghui  val Mcontrol     = Value(2.U)
195a7a6d0a6Schengguanghui  val Icount       = Value(3.U)
196a7a6d0a6Schengguanghui  val Itrigger     = Value(4.U)
197a7a6d0a6Schengguanghui  val Etrigger     = Value(5.U)
198a7a6d0a6Schengguanghui  val Mcontrol6    = Value(6.U)
199a7a6d0a6Schengguanghui  val Tmexttrigger = Value(7.U)
200a7a6d0a6Schengguanghui  val Disabled     = Value(15.U)
201a7a6d0a6Schengguanghui
202cc6e4cb5Schengguanghui  override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(Mcontrol6)
203a7a6d0a6Schengguanghui
204e3da8badSTang Haojin  override def legalize(enumeration: CSREnumType): CSREnumType = {
205e3da8badSTang Haojin    val res = WireInit(enumeration)
206e3da8badSTang Haojin    when(!enumeration.isLegal){
207a7a6d0a6Schengguanghui      res := Disabled.asUInt
208a7a6d0a6Schengguanghui    }
209a7a6d0a6Schengguanghui    res
210a7a6d0a6Schengguanghui  }
211a7a6d0a6Schengguanghui}
212a7a6d0a6Schengguanghui
213a7a6d0a6Schengguanghuiobject TrigAction extends CSREnum with WARLApply {
214a7a6d0a6Schengguanghui  val BreakpointExp = Value(0.U) // raise breakpoint exception
215a7a6d0a6Schengguanghui  val DebugMode     = Value(1.U) // enter debug mode
216a7a6d0a6Schengguanghui  val TraceOn       = Value(2.U)
217a7a6d0a6Schengguanghui  val TraceOff      = Value(3.U)
218a7a6d0a6Schengguanghui  val TraceNotify   = Value(4.U)
219a7a6d0a6Schengguanghui
220e3da8badSTang Haojin  override def isLegal(enumeration: CSREnumType, dmode: Bool): Bool = enumeration.isOneOf(BreakpointExp) || enumeration.isOneOf(DebugMode) && dmode
221a7a6d0a6Schengguanghui
222e3da8badSTang Haojin  override def legalize(enumeration: CSREnumType, dmode: Bool): CSREnumType = {
223e3da8badSTang Haojin    val res = WireInit(enumeration)
224e3da8badSTang Haojin    when(!enumeration.isLegal(dmode)){
225a7a6d0a6Schengguanghui      res := BreakpointExp
226a7a6d0a6Schengguanghui    }
227a7a6d0a6Schengguanghui    res.asInstanceOf[CSREnumType]
228a7a6d0a6Schengguanghui  }
229a7a6d0a6Schengguanghui}
230a7a6d0a6Schengguanghui
231a7a6d0a6Schengguanghuiobject TrigMatch extends CSREnum with WARLApply {
232a7a6d0a6Schengguanghui  val EQ        = Value(0.U)
233a7a6d0a6Schengguanghui  val NAPOT     = Value(1.U)
234a7a6d0a6Schengguanghui  val GE        = Value(2.U)
235a7a6d0a6Schengguanghui  val LT        = Value(3.U)
236a7a6d0a6Schengguanghui  val MASK_LO   = Value(4.U)
237a7a6d0a6Schengguanghui  val MASK_HI   = Value(5.U)
238a7a6d0a6Schengguanghui  val NE        = Value(8.U)  // not eq
239a7a6d0a6Schengguanghui  val NNAPOT    = Value(9.U)  // not napot
240a7a6d0a6Schengguanghui  val NMASK_LO  = Value(12.U) // not mask low
241a7a6d0a6Schengguanghui  val NMASK_HI  = Value(13.U) // not mask high
242e3da8badSTang Haojin  def isRVSpecLegal(enumeration: CSREnumType) : Bool = enumeration.isOneOf(
243a7a6d0a6Schengguanghui    EQ, NAPOT, GE, LT, MASK_LO, MASK_HI,
244a7a6d0a6Schengguanghui    NE, NNAPOT, NMASK_LO, NMASK_HI,
245a7a6d0a6Schengguanghui  )
246e3da8badSTang Haojin  override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(EQ, GE, LT)
247a7a6d0a6Schengguanghui
248e3da8badSTang Haojin  override def legalize(enumeration: CSREnumType): CSREnumType = {
249e3da8badSTang Haojin    val res = WireInit(enumeration)
250e3da8badSTang Haojin    when(!enumeration.isLegal){
251a7a6d0a6Schengguanghui      res := EQ
252a7a6d0a6Schengguanghui    }
253a7a6d0a6Schengguanghui    res.asInstanceOf[CSREnumType]
254a7a6d0a6Schengguanghui  }
255a7a6d0a6Schengguanghui}
256a7a6d0a6Schengguanghui
257a7a6d0a6Schengguanghui
258a7a6d0a6Schengguanghui// tdata2
259499d09b3SsinceforYyclass Tdata2Bundle extends OneFieldBundle
260a7a6d0a6Schengguanghui
261a7a6d0a6Schengguanghui// Tinfo
262a7a6d0a6Schengguanghuiclass TinfoBundle extends CSRBundle{
263a7a6d0a6Schengguanghui  // Version isn't in version 0.13
264a7a6d0a6Schengguanghui  val VERSION     = RO(31, 24).withReset(0.U)
265cc6e4cb5Schengguanghui  // only support mcontrol6
266cc6e4cb5Schengguanghui  val MCONTROL6EN = RO(6).withReset(1.U)
267a7a6d0a6Schengguanghui}
268a7a6d0a6Schengguanghui
269a7a6d0a6Schengguanghui// Dscratch
270499d09b3SsinceforYyclass DscratchBundle extends OneFieldBundle
271a7a6d0a6Schengguanghui
272a7a6d0a6Schengguanghui
273223cba9dSXuan Huclass DcsrBundle extends CSRBundle {
274a7a6d0a6Schengguanghui  override val len: Int = 32
275*39ec22f6SGuanghui Cheng  val DEBUGVER  = DcsrDebugVer(31, 28).withReset(DcsrDebugVer.Spec) // Debug implementation as it described in 0.13 draft
2761e49aeedSchengguanghui  val EXTCAUSE  =           RO(26, 24).withReset(0.U)
2771e49aeedSchengguanghui  val CETRIG    =           RW(    19).withReset(0.U)
278223cba9dSXuan Hu  // All ebreak Privileges are RW, instead of WARL, since XiangShan support U/S/VU/VS.
279223cba9dSXuan Hu  val EBREAKVS  =           RW(    17).withReset(0.U)
280223cba9dSXuan Hu  val EBREAKVU  =           RW(    16).withReset(0.U)
281223cba9dSXuan Hu  val EBREAKM   =           RW(    15).withReset(0.U)
282223cba9dSXuan Hu  val EBREAKS   =           RW(    13).withReset(0.U)
283223cba9dSXuan Hu  val EBREAKU   =           RW(    12).withReset(0.U)
284223cba9dSXuan Hu  // STEPIE is RW, instead of WARL, since XiangShan support interrupts being enabled single stepping.
285223cba9dSXuan Hu  val STEPIE    =           RW(    11).withReset(0.U)
2861e49aeedSchengguanghui  val STOPCOUNT =           RW(    10).withReset(0.U)
2871e49aeedSchengguanghui  val STOPTIME  =           RW(     9).withReset(0.U)
288a7a6d0a6Schengguanghui  val CAUSE     =    DcsrCause( 8,  6).withReset(DcsrCause.None)
289223cba9dSXuan Hu  val V         =     VirtMode(     5).withReset(VirtMode.Off)
290223cba9dSXuan Hu  // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode
291223cba9dSXuan Hu  // Whether use mstatus.mprv
292223cba9dSXuan Hu  val MPRVEN    =           RW(     4).withReset(0.U)
293223cba9dSXuan Hu  val NMIP      =           RO(     3).withReset(0.U)
294223cba9dSXuan Hu  // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode
295223cba9dSXuan Hu  val STEP      =           RW(     2).withReset(0.U)
296223cba9dSXuan Hu  val PRV       =     PrivMode( 1,  0).withReset(PrivMode.M)
297223cba9dSXuan Hu}
298223cba9dSXuan Hu
299223cba9dSXuan Huobject DcsrDebugVer extends CSREnum with ROApply {
300223cba9dSXuan Hu  val None    = Value(0.U)
301223cba9dSXuan Hu  val Spec    = Value(4.U)
302223cba9dSXuan Hu  val Custom  = Value(15.U)
303223cba9dSXuan Hu}
304223cba9dSXuan Hu
305223cba9dSXuan Huobject DcsrCause extends CSREnum with ROApply {
306a7a6d0a6Schengguanghui  val None         = Value(0.U)
307a7a6d0a6Schengguanghui  val Ebreak       = Value(1.U)
308a7a6d0a6Schengguanghui  val Trigger      = Value(2.U)
309a7a6d0a6Schengguanghui  val Haltreq      = Value(3.U)
310a7a6d0a6Schengguanghui  val Step         = Value(4.U)
311a7a6d0a6Schengguanghui  val Resethaltreq = Value(5.U)
312a7a6d0a6Schengguanghui  val Group        = Value(6.U)
313a751b11aSchengguanghui  val Other        = Value(7.U)
314a7a6d0a6Schengguanghui}
315a7a6d0a6Schengguanghui
316a7a6d0a6Schengguanghuitrait HasTdataSink { self: CSRModule[_] =>
317a7a6d0a6Schengguanghui  val tdataRead = IO(Input(new Bundle {
318*39ec22f6SGuanghui Cheng    val tdata1 = UInt(XLEN.W)
319a7a6d0a6Schengguanghui    val tdata2 = UInt(XLEN.W)
320a7a6d0a6Schengguanghui  }))
321a7a6d0a6Schengguanghui}
322*39ec22f6SGuanghui Chengtrait HasTriggerBundle { self: CSRModule[_] =>
323*39ec22f6SGuanghui Cheng  val canWriteDmode = IO(Input(Bool()))
324a7a6d0a6Schengguanghui  val chainable = IO(Input(Bool()))
325a7a6d0a6Schengguanghui}
326a7a6d0a6Schengguanghui
327a751b11aSchengguanghuitrait HasNmipBundle { self: CSRModule[_] =>
328a751b11aSchengguanghui  val nmip = IO(Input(Bool()))
329a751b11aSchengguanghui}
330a751b11aSchengguanghui
331a7a6d0a6Schengguanghui/**
332a7a6d0a6Schengguanghui * debug Module MMIO Addr
333a7a6d0a6Schengguanghui */
334a7a6d0a6Schengguanghuitrait DebugMMIO {
335a7a6d0a6Schengguanghui  implicit val p: Parameters
336a7a6d0a6Schengguanghui
337a7a6d0a6Schengguanghui  def debugMMIO = p(DebugModuleKey).get
338a7a6d0a6Schengguanghui
339a7a6d0a6Schengguanghui  def BASE = debugMMIO.baseAddress
340a7a6d0a6Schengguanghui  def DebugEntry     = BASE + 0x800
341a7a6d0a6Schengguanghui  def DebugException = BASE + 0x808
342a7a6d0a6Schengguanghui  def HALTED         = BASE + 0x100
343a7a6d0a6Schengguanghui  def GOING          = BASE + 0x104
344a7a6d0a6Schengguanghui  def RESUMING       = BASE + 0x108
345a7a6d0a6Schengguanghui  def EXCEPTION      = BASE + 0x10C
346a7a6d0a6Schengguanghui  def WHERETO        = BASE + 0x300
347a7a6d0a6Schengguanghui  def DATA           = BASE + 0x380
348a7a6d0a6Schengguanghui  def IMPEBREAK      = DATA - 0x4
349a7a6d0a6Schengguanghui  def PROGBUF        = DATA - 4 * debugMMIO.nProgramBufferWords
350a7a6d0a6Schengguanghui  def ABSTRACT       = PROGBUF - 4 * (if(debugMMIO.atzero) 2 else 5)
351a7a6d0a6Schengguanghui  def FLAGS          = BASE + 0x400
352a7a6d0a6Schengguanghui}
353a7a6d0a6Schengguanghui
354a7a6d0a6Schengguanghuiobject TriggerUtil {
355a7a6d0a6Schengguanghui  /**
356a7a6d0a6Schengguanghui   * Check if chain vector is legal
357a7a6d0a6Schengguanghui   * @param chainVec
358a7a6d0a6Schengguanghui   * @param chainLen
359a7a6d0a6Schengguanghui   * @return true.B if the max length of chain don't exceed the permitted length
360a7a6d0a6Schengguanghui   */
361a7a6d0a6Schengguanghui  def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = {
362a7a6d0a6Schengguanghui    !ConsecutiveOnes(chainVec, chainLen)
363a7a6d0a6Schengguanghui  }
3647e0f64b0SGuanghui Cheng
3657e0f64b0SGuanghui Cheng  /**
3667e0f64b0SGuanghui Cheng   * Generate Trigger action
3677e0f64b0SGuanghui Cheng   * @return triggerAction return
3687e0f64b0SGuanghui Cheng   * @param  triggerCanFireVec
3697e0f64b0SGuanghui Cheng   * @param  actionVec tdata.action
3707e0f64b0SGuanghui Cheng   * @param  triggerCanRaiseBpExp from csr
3717e0f64b0SGuanghui Cheng   */
3727e0f64b0SGuanghui Cheng  def triggerActionGen(triggerAction: UInt, triggerCanFireVec: Vec[Bool], actionVec: Vec[UInt], triggerCanRaiseBpExp: Bool): Unit = {
3737e0f64b0SGuanghui Cheng    // More than one triggers can hit at the same time, but only fire one.
3747e0f64b0SGuanghui Cheng    // We select the first hit trigger to fire.
3757e0f64b0SGuanghui Cheng    val hasTriggerFire    = triggerCanFireVec.asUInt.orR
3767e0f64b0SGuanghui Cheng    val triggerFireOH     = PriorityEncoderOH(triggerCanFireVec)
3777e0f64b0SGuanghui Cheng    val triggerFireAction = PriorityMux(triggerFireOH, actionVec).asUInt
3787e0f64b0SGuanghui Cheng    val actionIsBPExp     = hasTriggerFire && (triggerFireAction === TrigAction.BreakpointExp.asUInt)
3797e0f64b0SGuanghui Cheng    val actionIsDmode     = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt)
3807e0f64b0SGuanghui Cheng    val breakPointExp     = actionIsBPExp && triggerCanRaiseBpExp
3817e0f64b0SGuanghui Cheng
3827e0f64b0SGuanghui Cheng    // todo: add more for trace
3837e0f64b0SGuanghui Cheng    triggerAction := MuxCase(TriggerAction.None, Seq(
3847e0f64b0SGuanghui Cheng      breakPointExp -> TriggerAction.BreakpointExp,
3857e0f64b0SGuanghui Cheng      actionIsDmode -> TriggerAction.DebugMode,
3867e0f64b0SGuanghui Cheng    ))
3877e0f64b0SGuanghui Cheng  }
388223cba9dSXuan Hu}