xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryMNEvent.scala (revision c1b28b66879239a5b3a44741376f3b002e8ac834)
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._
11import xiangshan.AddrTransType
12
13class TrapEntryMNEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase  {
14  val mnstatus = ValidIO((new MnstatusBundle ).addInEvent(_.MNPP, _.MNPV, _.NMIE))
15  val mnepc    = ValidIO((new Epc           ).addInEvent(_.epc))
16  val mncause  = ValidIO((new CauseBundle   ).addInEvent(_.Interrupt, _.ExceptionCode))
17  val targetPc = ValidIO(new TargetPCBundle)
18
19  def getBundleByName(name: String): Valid[CSRBundle] = {
20    name match {
21      case "mnstatus"  => this.mnstatus
22      case "mnepc"     => this.mnepc
23      case "mncause"   => this.mncause
24    }
25  }
26}
27
28class TrapEntryMNEventModule(implicit val p: Parameters) extends Module with CSREventBase {
29  val in = IO(new TrapEntryEventInput)
30  val out = IO(new TrapEntryMNEventOutput)
31
32  private val current = in
33  private val iMode = current.iMode
34  private val satp  = current.satp
35  private val vsatp = current.vsatp
36  private val hgatp = current.hgatp
37
38  private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt
39  private val isInterrupt = in.causeNO.Interrupt.asBool
40
41  private val isFetchMalAddr = in.isFetchMalAddr
42
43  private val trapPC = genTrapVA(
44    iMode,
45    satp,
46    vsatp,
47    hgatp,
48    in.trapPc,
49  )
50  out := DontCare
51
52  out.privState.valid := valid
53  out.mnstatus.valid  := valid
54  out.mnepc.valid     := valid
55  out.mncause.valid   := valid
56  out.targetPc.valid  := valid
57
58  out.privState.bits             := PrivState.ModeM
59  out.mnstatus.bits.MNPP         := current.privState.PRVM
60  out.mnstatus.bits.MNPV         := current.privState.V
61  out.mnstatus.bits.NMIE         := 0.U
62  out.mnepc.bits.epc             := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1))
63  out.mncause.bits.Interrupt     := isInterrupt
64  out.mncause.bits.ExceptionCode := highPrioTrapNO
65  out.targetPc.bits.pc           := in.pcFromXtvec
66  out.targetPc.bits.raiseIPF     := false.B
67  out.targetPc.bits.raiseIAF     := AddrTransType(bare = true).checkAccessFault(in.pcFromXtvec)
68  out.targetPc.bits.raiseIGPF    := false.B
69
70}
71
72trait TrapEntryMNEventSinkBundle { self: CSRModule[_] =>
73  val trapToMN = IO(Flipped(new TrapEntryMNEventOutput))
74
75  private val updateBundle: ValidIO[CSRBundle] = trapToMN.getBundleByName(self.modName.toLowerCase())
76
77  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
78    if (updateBundle.bits.eventFields.contains(source)) {
79      when(updateBundle.valid) {
80        sink := source
81      }
82    }
83  }
84}
85