xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala (revision 1734111c27f9c4e87629d9013f62b5dbf95e88d0)
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 Dpc       ).addInEvent(_.ALL))
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 hasTrap                 = in.hasTrap
47  private val debugMode               = in.debugMode
48  private val hasDebugIntr            = in.hasDebugIntr
49  private val breakPoint              = in.breakPoint
50  private val hasTriggerFire          = in.hasTriggerFire
51  private val hasDebugEbreakException = in.hasDebugEbreakException
52  private val hasSingleStep           = in.hasSingleStep
53
54  private val hasExceptionInDmode = debugMode && hasTrap
55  val causeIntr = DcsrCause.Haltreq.asUInt
56  val causeExp = MuxCase(0.U, Seq(
57    hasTriggerFire          -> DcsrCause.Trigger.asUInt,
58    hasDebugEbreakException -> DcsrCause.Ebreak.asUInt,
59    hasSingleStep           -> DcsrCause.Step.asUInt
60  ))
61
62  private val trapPC = Wire(UInt(XLEN.W))
63  private val ivmHS = !current.iMode.isModeHS && current.satp.MODE =/= SatpMode.Bare
64  private val ivmVS = !current.iMode.isModeVS && current.vsatp.MODE =/= SatpMode.Bare
65  // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57
66  trapPC := Mux(ivmHS || ivmVS, SignExt(in.trapPc, XLEN), ZeroExt(in.trapPc, XLEN))
67
68  // ebreak jump debugEntry not debugException in dmode
69  // debug rom make hart write 0 to DebugMMIO.EXCEPTION when exception happened in debugMode.
70  // let debug module known hart got an exception.
71  // note: Need't know exception number in debugMode.
72  //       exception(EX_BP) must be ebreak here!
73  val debugPc = Mux(hasExceptionInDmode && !breakPoint, DebugException.U, DebugEntry.U)
74
75  out := DontCare
76  // output
77  out.dcsr.valid            := valid
78  out.dpc.valid             := valid
79  // !debugMode trap || debugMode hasExp
80  out.targetPc.valid        := valid || hasExceptionInDmode
81  out.debugMode.valid       := valid
82  out.privState.valid       := valid
83  out.debugIntrEnable.valid := valid
84
85  out.dcsr.bits.V           := current.privState.V.asUInt
86  out.dcsr.bits.PRV         := current.privState.PRVM.asUInt
87  out.dcsr.bits.CAUSE       := Mux(hasDebugIntr, causeIntr, causeExp)
88  out.dpc.bits              := trapPC
89
90  out.targetPc.bits         := debugPc
91  out.debugMode.bits        := true.B
92  out.privState.bits        := PrivState.ModeM
93  out.debugIntrEnable.bits  := false.B
94
95}
96
97trait TrapEntryDEventSinkBundle { self: CSRModule[_] =>
98  val trapToD = IO(Flipped(new TrapEntryDEventOutput))
99
100  private val updateBundle: ValidIO[CSRBundle] = trapToD.getBundleByName(self.modName.toLowerCase())
101
102  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
103    if (updateBundle.bits.eventFields.contains(source)) {
104      when(updateBundle.valid) {
105        sink := source
106      }
107    }
108  }
109}
110