xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/MNretEvent.scala (revision e1d5ffc2d93873b72146e78c8f6a904926de8590)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import utility.{SignExt, ZeroExt}
6import xiangshan.ExceptionNO
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.CSRDefines.{PrivMode, SatpMode, VirtMode}
11import xiangshan.backend.fu.NewCSR._
12
13
14class MNretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
15  val mnstatus  = ValidIO((new MnstatusBundle).addInEvent(_.MNPP, _.MNPV, _.NMIE))
16  val mstatus   = ValidIO((new MstatusBundle).addInEvent(_.MPRV))
17  val targetPc  = ValidIO(UInt(VaddrMaxWidth.W))
18
19  override def getBundleByName(name: String): ValidIO[CSRBundle] = {
20    name match {
21      case "mnstatus"  => this.mnstatus
22      case "mstatus"   => this.mstatus
23    }
24  }
25}
26
27class MNretEventInput extends Bundle {
28  val mnstatus = Input(new MnstatusBundle)
29  val mstatus  = Input(new MstatusBundle)
30  val mnepc   = Input(new Epc())
31}
32
33class MNretEventModule extends Module with CSREventBase {
34  val in = IO(new MNretEventInput)
35  val out = IO(new MNretEventOutput)
36
37  out := DontCare
38
39  out.privState.valid := valid
40  out.mnstatus .valid := valid
41  out.targetPc .valid := valid
42
43  out.privState.bits.PRVM := in.mnstatus.MNPP
44  out.privState.bits.V    := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)
45  out.mnstatus.bits.MNPP  := PrivMode.U
46  out.mnstatus.bits.MNPV  := VirtMode.Off.asUInt
47  out.mnstatus.bits.NMIE  := 1.U
48  out.mstatus.bits.MPRV   := Mux(in.mnstatus.MNPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
49  out.targetPc.bits       := in.mnepc.asUInt
50}
51
52trait MNretEventSinkBundle { self: CSRModule[_] =>
53  val retFromMN = IO(Flipped(new MNretEventOutput))
54
55  private val updateBundle: ValidIO[CSRBundle] = retFromMN.getBundleByName(self.modName.toLowerCase())
56
57  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
58    if (updateBundle.bits.eventFields.contains(source)) {
59      when(updateBundle.valid) {
60        sink := source
61      }
62    }
63  }
64
65}