xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/MretEvent.scala (revision 25dc4a827ee27e3ccbaf02e8e5134872cba28fcd)
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}
11import xiangshan.backend.fu.NewCSR._
12
13
14class MretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
15  val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPP, _.MPV, _.MIE, _.MPIE, _.MPRV))
16  val targetPc = ValidIO(UInt(VaddrMaxWidth.W))
17
18  override def getBundleByName(name: String): ValidIO[CSRBundle] = {
19    name match {
20      case "mstatus" => this.mstatus
21    }
22  }
23}
24
25class MretEventInput extends Bundle {
26  val mstatus = Input(new MstatusBundle)
27  val mepc = Input(new Epc())
28}
29
30class MretEventModule extends Module with CSREventBase {
31  val in = IO(new MretEventInput)
32  val out = IO(new MretEventOutput)
33
34  out := DontCare
35
36  out.privState.valid := valid
37  out.mstatus  .valid := valid
38  out.targetPc .valid := valid
39
40  out.privState.bits.PRVM := in.mstatus.MPP
41  out.privState.bits.V    := in.mstatus.MPV
42  out.mstatus.bits.MPP    := PrivMode.U
43  out.mstatus.bits.MIE    := in.mstatus.MPIE
44  out.mstatus.bits.MPIE   := 1.U
45  out.mstatus.bits.MPRV   := Mux(in.mstatus.MPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
46  out.targetPc.bits       := in.mepc.asUInt
47}
48
49trait MretEventSinkBundle { self: CSRModule[_] =>
50  val retFromM = IO(Flipped(new MretEventOutput))
51
52  private val updateBundle: ValidIO[CSRBundle] = retFromM.getBundleByName(self.modName.toLowerCase())
53
54  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
55    if (updateBundle.bits.eventFields.contains(source)) {
56      when(updateBundle.valid) {
57        sink := source
58      }
59    }
60  }
61
62}
63