xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala (revision 0f9a14c67d1bdaf37c3913b2215d99f91b6d4482)
1package xiangshan.backend.fu.NewCSR
2
3import freechips.rocketchip.devices.debug.DebugModuleKey
4import org.chipsalliance.cde.config.Parameters
5import freechips.rocketchip.rocket.CSRs
6
7import chisel3._
8import chisel3.util._
9import utils.ConsecutiveOnes
10import xiangshan.backend.fu.NewCSR.CSRDefines._
11import xiangshan.backend.fu.NewCSR.CSRDefines.{
12  CSRWARLField => WARL,
13  CSRRWField => RW,
14  CSRROField => RO,
15}
16import xiangshan.backend.fu.NewCSR.CSRFunc._
17import xiangshan.backend.fu.NewCSR.CSREvents._
18import CSRConfig._
19import utility.SignExt
20import scala.collection.immutable.SeqMap
21
22
23trait DebugLevel { self: NewCSR =>
24  val tselect = Module(new CSRModule("Tselect", new TselectBundle(TriggerNum)))
25    .setAddr(CSRs.tselect)
26
27  val tdata1 = Module(new CSRModule("Tdata1") with HasTdataSink {
28    regOut := tdataRead.tdata1
29  })
30    .setAddr(CSRs.tdata1)
31
32  val tdata2 = Module(new CSRModule("Tdata2") with HasTdataSink {
33    regOut := tdataRead.tdata2
34  })
35    .setAddr(CSRs.tdata2)
36
37  val tdata1RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i =>
38    Module(new CSRModule(s"Trigger$i" + s"_Tdata1", new Tdata1Bundle) with HasdebugModeBundle {
39      when(wen){
40        reg := wdata.writeTdata1(debugMode, chainable).asUInt
41      }
42    })
43  )
44  val tdata2RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i =>
45    Module(new CSRModule(s"Trigger$i" + s"_Tdata2", new Tdata2Bundle))
46  )
47
48  val tinfo = Module(new CSRModule("Tinfo", new TinfoBundle))
49    .setAddr(CSRs.tinfo)
50
51  val tcontrol = Module(new CSRModule("Tcontrol", new TcontrolBundle) with TrapEntryMEventSinkBundle with MretEventSinkBundle)
52    .setAddr(CSRs.tcontrol)
53
54  val dcsr = Module(new CSRModule("Dcsr", new DcsrBundle) with TrapEntryDEventSinkBundle with DretEventSinkBundle)
55    .setAddr(CSRs.dcsr)
56
57  val dpc = Module(new CSRModule("Dpc", new Epc) with TrapEntryDEventSinkBundle {
58    rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
59  })
60    .setAddr(CSRs.dpc)
61
62  val dscratch0 = Module(new CSRModule("Dscratch0", new DscratchBundle))
63    .setAddr(CSRs.dscratch0)
64
65  val dscratch1 = Module(new CSRModule("Dscratch1", new DscratchBundle))
66    .setAddr(CSRs.dscratch1)
67
68  val debugCSRMods = Seq(
69    tdata1,
70    tdata2,
71    tselect,
72    tinfo,
73    tcontrol,
74    dcsr,
75    dpc,
76    dscratch0,
77    dscratch1,
78  )
79
80  val debugCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_ <: CSRBundle], UInt)] = SeqMap.from(
81    debugCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata)).iterator
82  )
83
84  val debugCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
85    debugCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator
86  )
87
88  private val tdata1Rdata = Mux1H(
89    tdata1RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata}
90  )
91
92  private val tdata2Rdata = Mux1H(
93    tdata2RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata}
94  )
95
96  debugCSRMods.foreach { mod =>
97    mod match {
98      case m: HasTdataSink =>
99        m.tdataRead.tdata1 := tdata1Rdata
100        m.tdataRead.tdata2 := tdata2Rdata
101      case _ =>
102    }
103  }
104
105}
106
107// tselect
108class TselectBundle(triggerNum: Int) extends CSRBundle{
109  override val len: Int = log2Up(triggerNum)
110  val ALL = WARL(len - 1, 0, wNoEffectWhen(WriteTselect))
111  def WriteTselect(wdata: UInt) = {
112    wdata >= triggerNum.U
113  }
114}
115
116// tdata1
117class Tdata1Bundle extends CSRBundle{
118  val TYPE    = Tdata1Type(63, 60, wNoFilter).withReset(Tdata1Type.Disabled)
119  val DMODE   = RW(59).withReset(0.U)
120  val DATA    = RW(58, 0)
121
122  def getTriggerAction: CSREnumType = {
123    val res = Wire(new Mcontrol)
124    res := this.asUInt
125    res.ACTION
126  }
127
128  def writeTdata1(debugMode: Bool, chainable: Bool): Tdata1Bundle = {
129    val res = Wire(new Tdata1Bundle)
130    res := this.asUInt
131    val dmode = this.DMODE.asBool && debugMode
132    res.TYPE := this.TYPE.legalize.asUInt
133    res.DMODE := dmode
134    when(this.TYPE.isLegal) {
135      val mcontrolRes = Wire(new Mcontrol)
136      mcontrolRes := this.DATA.asUInt
137      res.DATA := mcontrolRes.writeData(dmode, chainable).asUInt
138    }.otherwise{
139      res.DATA := 0.U
140    }
141   res
142  }
143}
144
145class Mcontrol extends CSRBundle{
146  override val len: Int = 59
147  // xiangshan don't support match = NAPOT
148  val MASKMAX = RO(58, 53).withReset(0.U)
149  val SIZEHI  = RW(22, 21).withReset(0.U)
150  val HIT     = RW(20).withReset(0.U)
151  val SELECT  = RW(19).withReset(0.U)
152  val TIMING  = RW(18).withReset(0.U)
153  val SIZELO  = RW(17, 16).withReset(0.U)
154  val ACTION  = TrigAction(15, 12, wNoFilter).withReset(TrigAction.BreakpointExp)
155  val CHAIN   = RW(11).withReset(0.U)
156  val MATCH   = TrigMatch(10, 7, wNoFilter).withReset(TrigMatch.EQ)
157  val M       = RW(6).withReset(0.U)
158  val S       = RW(4).withReset(0.U)
159  val U       = RW(3).withReset(0.U)
160  val EXECUTE = RW(2).withReset(0.U)
161  val STORE   = RW(1).withReset(0.U)
162  val LOAD    = RW(0).withReset(0.U)
163
164  def writeData(dmode: Bool, chainable: Bool): Mcontrol = {
165    val res = Wire(new Mcontrol)
166    res := this.asUInt
167    res.MASKMAX     := 0.U
168    res.SIZEHI      := 0.U
169    res.HIT         := false.B
170    res.SELECT      := this.EXECUTE.asBool && this.SELECT.asBool
171    res.TIMING      := false.B
172    res.SIZELO      := 0.U
173    res.ACTION      := this.ACTION.legalize(dmode).asUInt
174    res.CHAIN       := this.CHAIN.asBool && chainable
175    res.MATCH       := this.MATCH.legalize.asUInt
176    res
177  }
178  def isFetchTrigger: Bool = this.EXECUTE.asBool
179  def isMemAccTrigger: Bool = this.STORE || this.LOAD
180}
181
182
183object Tdata1Type extends CSREnum with WARLApply {
184  val None         = Value(0.U)
185  val Legacy       = Value(1.U)
186  val Mcontrol     = Value(2.U)
187  val Icount       = Value(3.U)
188  val Itrigger     = Value(4.U)
189  val Etrigger     = Value(5.U)
190  val Mcontrol6    = Value(6.U)
191  val Tmexttrigger = Value(7.U)
192  val Disabled     = Value(15.U)
193
194  override def isLegal(enum: CSREnumType): Bool = enum.isOneOf(Mcontrol)
195
196  override def legalize(enum: CSREnumType): CSREnumType = {
197    val res = WireInit(enum)
198    when(!enum.isLegal){
199      res := Disabled.asUInt
200    }
201    res
202  }
203}
204
205object TrigAction extends CSREnum with WARLApply {
206  val BreakpointExp = Value(0.U) // raise breakpoint exception
207  val DebugMode     = Value(1.U) // enter debug mode
208  val TraceOn       = Value(2.U)
209  val TraceOff      = Value(3.U)
210  val TraceNotify   = Value(4.U)
211
212  override def isLegal(enum: CSREnumType, dmode: Bool): Bool = enum.isOneOf(BreakpointExp) || enum.isOneOf(DebugMode) && dmode
213
214  override def legalize(enum: CSREnumType, dmode: Bool): CSREnumType = {
215    val res = WireInit(enum)
216    when(!enum.isLegal(dmode)){
217      res := BreakpointExp
218    }
219    res.asInstanceOf[CSREnumType]
220  }
221}
222
223object TrigMatch extends CSREnum with WARLApply {
224  val EQ        = Value(0.U)
225  val NAPOT     = Value(1.U)
226  val GE        = Value(2.U)
227  val LT        = Value(3.U)
228  val MASK_LO   = Value(4.U)
229  val MASK_HI   = Value(5.U)
230  val NE        = Value(8.U)  // not eq
231  val NNAPOT    = Value(9.U)  // not napot
232  val NMASK_LO  = Value(12.U) // not mask low
233  val NMASK_HI  = Value(13.U) // not mask high
234  def isRVSpecLegal(enum: CSREnumType) : Bool = enum.isOneOf(
235    EQ, NAPOT, GE, LT, MASK_LO, MASK_HI,
236    NE, NNAPOT, NMASK_LO, NMASK_HI,
237  )
238  override def isLegal(enum: CSREnumType): Bool = enum.isOneOf(EQ, GE, LT)
239
240  override def legalize(enum: CSREnumType): CSREnumType = {
241    val res = WireInit(enum)
242    when(!enum.isLegal){
243      res := EQ
244    }
245    res.asInstanceOf[CSREnumType]
246  }
247}
248
249
250// tdata2
251class Tdata2Bundle extends CSRBundle{
252  val ALL = RW(63, 0)
253}
254
255// Tinfo
256class TinfoBundle extends CSRBundle{
257  // Version isn't in version 0.13
258  val VERSION     = RO(31, 24).withReset(0.U)
259  // only support mcontrol
260  val MCONTROLEN  = RO(2).withReset(1.U)
261}
262
263class TcontrolBundle extends CSRBundle{
264  // M-mode previous trigger enable field
265  val MPTE = RW(7).withReset(0.U)
266  // M-mode trigger enable field
267  val MTE  = RW(3).withReset(0.U)
268}
269
270// Dscratch
271class DscratchBundle extends CSRBundle{
272  val ALL   = RW(63, 0)
273}
274
275
276class DcsrBundle extends CSRBundle {
277  override val len: Int = 32
278  val DEBUGVER  = DcsrDebugVer(31, 28).withReset(DcsrDebugVer.Spec) // Debug implementation as it described in 0.13 draft // todo
279  // All ebreak Privileges are RW, instead of WARL, since XiangShan support U/S/VU/VS.
280  val EBREAKVS  =           RW(    17).withReset(0.U)
281  val EBREAKVU  =           RW(    16).withReset(0.U)
282  val EBREAKM   =           RW(    15).withReset(0.U)
283  val EBREAKS   =           RW(    13).withReset(0.U)
284  val EBREAKU   =           RW(    12).withReset(0.U)
285  // STEPIE is RW, instead of WARL, since XiangShan support interrupts being enabled single stepping.
286  val STEPIE    =           RW(    11).withReset(0.U)
287  val STOPCOUNT =           RO(    10).withReset(0.U) // Stop count updating has not been supported
288  val STOPTIME  =           RO(     9).withReset(0.U) // Stop time updating has not been supported
289  val CAUSE     =    DcsrCause( 8,  6).withReset(DcsrCause.None)
290  val V         =     VirtMode(     5).withReset(VirtMode.Off)
291  // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode
292  // Whether use mstatus.mprv
293  val MPRVEN    =           RW(     4).withReset(0.U)
294  // TODO: support non-maskable interrupt
295  val NMIP      =           RO(     3).withReset(0.U)
296  // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode
297  val STEP      =           RW(     2).withReset(0.U)
298  val PRV       =     PrivMode( 1,  0).withReset(PrivMode.M)
299}
300
301object DcsrDebugVer extends CSREnum with ROApply {
302  val None    = Value(0.U)
303  val Spec    = Value(4.U)
304  val Custom  = Value(15.U)
305}
306
307object DcsrCause extends CSREnum with ROApply {
308  val None         = Value(0.U)
309  val Ebreak       = Value(1.U)
310  val Trigger      = Value(2.U)
311  val Haltreq      = Value(3.U)
312  val Step         = Value(4.U)
313  val Resethaltreq = Value(5.U)
314  val Group        = Value(6.U)
315}
316
317trait HasTdataSink { self: CSRModule[_] =>
318  val tdataRead = IO(Input(new Bundle {
319    val tdata1 = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width
320    val tdata2 = UInt(XLEN.W)
321  }))
322}
323trait HasdebugModeBundle { self: CSRModule[_] =>
324  val debugMode = IO(Input(Bool()))
325  val chainable = IO(Input(Bool()))
326}
327
328/**
329 * debug Module MMIO Addr
330 */
331trait DebugMMIO {
332  implicit val p: Parameters
333
334  def debugMMIO = p(DebugModuleKey).get
335
336  def BASE = debugMMIO.baseAddress
337  def DebugEntry     = BASE + 0x800
338  def DebugException = BASE + 0x808
339  def HALTED         = BASE + 0x100
340  def GOING          = BASE + 0x104
341  def RESUMING       = BASE + 0x108
342  def EXCEPTION      = BASE + 0x10C
343  def WHERETO        = BASE + 0x300
344  def DATA           = BASE + 0x380
345  def IMPEBREAK      = DATA - 0x4
346  def PROGBUF        = DATA - 4 * debugMMIO.nProgramBufferWords
347  def ABSTRACT       = PROGBUF - 4 * (if(debugMMIO.atzero) 2 else 5)
348  def FLAGS          = BASE + 0x400
349}
350
351object TriggerUtil {
352  /**
353   * Check if chain vector is legal
354   * @param chainVec
355   * @param chainLen
356   * @return true.B if the max length of chain don't exceed the permitted length
357   */
358  def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = {
359    !ConsecutiveOnes(chainVec, chainLen)
360  }
361}