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