xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryMNEvent.scala (revision e1d5ffc2d93873b72146e78c8f6a904926de8590)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.SignExt
7import xiangshan.ExceptionNO
8import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState}
9import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN}
10import xiangshan.backend.fu.NewCSR._
11
12class TrapEntryMNEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase  {
13  val mnstatus = ValidIO((new MnstatusBundle ).addInEvent(_.MNPP, _.MNPV, _.NMIE))
14  val mnepc    = ValidIO((new Epc           ).addInEvent(_.epc))
15  val mncause  = ValidIO((new CauseBundle   ).addInEvent(_.Interrupt, _.ExceptionCode))
16  val targetPc = ValidIO(UInt(VaddrMaxWidth.W))
17
18  def getBundleByName(name: String): Valid[CSRBundle] = {
19    name match {
20      case "mnstatus"  => this.mnstatus
21      case "mnepc"     => this.mnepc
22      case "mncause"   => this.mncause
23    }
24  }
25}
26
27class TrapEntryMNEventModule(implicit val p: Parameters) extends Module with CSREventBase {
28  val in = IO(new TrapEntryEventInput)
29  val out = IO(new TrapEntryMNEventOutput)
30
31  private val current = in
32  private val iMode = current.iMode
33  private val satp  = current.satp
34  private val vsatp = current.vsatp
35  private val hgatp = current.hgatp
36
37  private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt
38  private val isInterrupt = in.causeNO.Interrupt.asBool
39
40  private val trapPC = genTrapVA(
41    iMode,
42    satp,
43    vsatp,
44    hgatp,
45    in.trapPc,
46  )
47  out := DontCare
48
49  out.privState.valid := valid
50  out.mnstatus.valid  := valid
51  out.mnepc.valid     := valid
52  out.mncause.valid   := valid
53  out.targetPc.valid  := valid
54
55  out.privState.bits             := PrivState.ModeM
56  out.mnstatus.bits.MNPP         := current.privState.PRVM
57  out.mnstatus.bits.MNPV         := current.privState.V
58  out.mnstatus.bits.NMIE         := 0.U
59  out.mnepc.bits.epc             := trapPC(VaddrMaxWidth - 1, 1)
60  out.mncause.bits.Interrupt     := isInterrupt
61  out.mncause.bits.ExceptionCode := highPrioTrapNO
62  out.targetPc.bits              := in.pcFromXtvec
63
64}
65
66trait TrapEntryMNEventSinkBundle { self: CSRModule[_] =>
67  val trapToMN = IO(Flipped(new TrapEntryMNEventOutput))
68
69  private val updateBundle: ValidIO[CSRBundle] = trapToMN.getBundleByName(self.modName.toLowerCase())
70
71  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
72    if (updateBundle.bits.eventFields.contains(source)) {
73      when(updateBundle.valid) {
74        sink := source
75      }
76    }
77  }
78}
79