xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala (revision b03c55a5df5dc8793cb44b42dd60141566e57e78)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util.{MuxCase, _}
5import org.chipsalliance.cde.config.Parameters
6import utility.{SignExt, ZeroExt}
7import xiangshan.{ExceptionNO, HasXSParameter, TriggerCf}
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(UInt(VaddrMaxWidth.W))
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 hasTriggerFire          = 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 hasTriggerFire          = in.hasTriggerFire
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    hasTriggerFire          -> 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(VaddrMaxWidth - 1, 1)
96
97  out.targetPc.bits         := debugPc
98  out.debugMode.bits        := true.B
99  out.privState.bits        := PrivState.ModeM
100  out.debugIntrEnable.bits  := false.B
101
102}
103
104trait TrapEntryDEventSinkBundle { self: CSRModule[_] =>
105  val trapToD = IO(Flipped(new TrapEntryDEventOutput))
106
107  private val updateBundle: ValidIO[CSRBundle] = trapToD.getBundleByName(self.modName.toLowerCase())
108
109  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
110    if (updateBundle.bits.eventFields.contains(source)) {
111      when(updateBundle.valid) {
112        sink := source
113      }
114    }
115  }
116}
117