xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala (revision 3088616cbf0793407bb68460b2db89b7de80c12a)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{SignExt, ZeroExt}
7import xiangshan.{ExceptionNO, HasXSParameter, TriggerAction}
8import xiangshan.ExceptionNO._
9import xiangshan.backend.fu.NewCSR
10import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState}
11import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN}
12import xiangshan.backend.fu.NewCSR.CSRDefines.SatpMode
13import xiangshan.backend.fu.NewCSR._
14
15
16class TrapEntryDEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
17  val dcsr            = ValidIO((new DcsrBundle).addInEvent(_.CAUSE, _.V, _.PRV))
18  val dpc             = ValidIO((new Epc       ).addInEvent(_.epc))
19  val targetPc        = ValidIO(new TargetPCBundle)
20  val debugMode       = ValidIO(Bool())
21  val debugIntrEnable = ValidIO(Bool())
22
23  def getBundleByName(name: String): Valid[CSRBundle] = {
24    name match {
25      case "dcsr" => this.dcsr
26      case "dpc"  => this.dpc
27    }
28  }
29}
30
31class TrapEntryDEventInput(implicit override val p: Parameters) extends TrapEntryEventInput{
32  val hasTrap                 = Input(Bool())
33  val debugMode               = Input(Bool())
34  val hasDebugIntr            = Input(Bool())
35  val triggerEnterDebugMode   = Input(Bool())
36  val hasDebugEbreakException = Input(Bool())
37  val hasSingleStep           = Input(Bool())
38  val breakPoint              = Input(Bool())
39}
40
41class TrapEntryDEventModule(implicit val p: Parameters) extends Module with CSREventBase with DebugMMIO {
42  val in = IO(new TrapEntryDEventInput)
43  val out = IO(new TrapEntryDEventOutput)
44
45  private val current = in
46  private val iMode   = current.iMode
47  private val satp    = current.satp
48  private val vsatp   = current.vsatp
49  private val hgatp   = current.hgatp
50
51  private val hasTrap                 = in.hasTrap
52  private val debugMode               = in.debugMode
53  private val hasDebugIntr            = in.hasDebugIntr
54  private val breakPoint              = in.breakPoint
55  private val triggerEnterDebugMode   = in.triggerEnterDebugMode
56  private val hasDebugEbreakException = in.hasDebugEbreakException
57  private val hasSingleStep           = in.hasSingleStep
58
59  private val hasExceptionInDmode = debugMode && hasTrap
60  val causeIntr = DcsrCause.Haltreq.asUInt
61  val causeExp = MuxCase(0.U, Seq(
62    triggerEnterDebugMode   -> DcsrCause.Trigger.asUInt,
63    hasDebugEbreakException -> DcsrCause.Ebreak.asUInt,
64    hasSingleStep           -> DcsrCause.Step.asUInt
65  ))
66
67  private val trapPC = genTrapVA(
68    iMode,
69    satp,
70    vsatp,
71    hgatp,
72    in.trapPc,
73  )
74
75  // ebreak jump debugEntry not debugException in dmode
76  // debug rom make hart write 0 to DebugMMIO.EXCEPTION when exception happened in debugMode.
77  // let debug module known hart got an exception.
78  // note: Need't know exception number in debugMode.
79  //       exception(EX_BP) must be ebreak here!
80  val debugPc = Mux(hasExceptionInDmode && !breakPoint, DebugException.U, DebugEntry.U)
81
82  out := DontCare
83  // output
84  out.dcsr.valid              := valid
85  out.dpc.valid               := valid
86  // !debugMode trap || debugMode hasExp
87  out.targetPc.valid          := valid || hasExceptionInDmode
88  out.debugMode.valid         := valid
89  out.privState.valid         := valid
90  out.debugIntrEnable.valid   := valid
91
92  out.dcsr.bits.V             := current.privState.V.asUInt
93  out.dcsr.bits.PRV           := current.privState.PRVM.asUInt
94  out.dcsr.bits.CAUSE         := Mux(hasDebugIntr, causeIntr, causeExp)
95  out.dpc.bits.epc            := trapPC(63, 1)
96
97  out.targetPc.bits.pc        := debugPc
98  out.targetPc.bits.raiseIPF  := false.B
99  out.targetPc.bits.raiseIAF  := false.B
100  out.targetPc.bits.raiseIGPF := false.B
101  out.debugMode.bits          := true.B
102  out.privState.bits          := PrivState.ModeM
103  out.debugIntrEnable.bits    := false.B
104
105}
106
107trait TrapEntryDEventSinkBundle { self: CSRModule[_] =>
108  val trapToD = IO(Flipped(new TrapEntryDEventOutput))
109
110  private val updateBundle: ValidIO[CSRBundle] = trapToD.getBundleByName(self.modName.toLowerCase())
111
112  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
113    if (updateBundle.bits.eventFields.contains(source)) {
114      when(updateBundle.valid) {
115        sink := source
116      }
117    }
118  }
119}
120