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