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