xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/SretEvent.scala (revision eca6983f19d9c20aa907987dff616649c3d204a2)
1237d4cfdSXuan Hupackage xiangshan.backend.fu.NewCSR.CSREvents
2237d4cfdSXuan Hu
3237d4cfdSXuan Huimport chisel3._
4237d4cfdSXuan Huimport chisel3.util._
5c1b28b66STang Haojinimport org.chipsalliance.cde.config.Parameters
6237d4cfdSXuan Huimport utility.{SignExt, ZeroExt}
7237d4cfdSXuan Huimport xiangshan.ExceptionNO
8237d4cfdSXuan Huimport xiangshan.ExceptionNO._
9237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState}
10237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN}
11c1b28b66STang Haojinimport xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, PrivMode, SatpMode, VirtMode}
12237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR._
13c1b28b66STang Haojinimport xiangshan.AddrTransType
14237d4cfdSXuan Hu
15237d4cfdSXuan Hu
16237d4cfdSXuan Huclass SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
17237d4cfdSXuan Hu  // Todo: write sstatus instead of mstatus
186808b803SZehao Liu  val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV, _.MDT, _.SDT))
19237d4cfdSXuan Hu  val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV))
20*eca6983fSZehao Liu  val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP))
21c1b28b66STang Haojin  val targetPc = ValidIO(new TargetPCBundle)
22237d4cfdSXuan Hu}
23237d4cfdSXuan Hu
24*eca6983fSZehao Liuclass SretEventSDTOutput extends Bundle with EventOutputBase {
25*eca6983fSZehao Liu  val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT))
26*eca6983fSZehao Liu}
27*eca6983fSZehao Liu
28237d4cfdSXuan Huclass SretEventInput extends Bundle {
29237d4cfdSXuan Hu  val privState = Input(new PrivState)
306808b803SZehao Liu  val mstatus   = Input(new MstatusBundle)
31237d4cfdSXuan Hu  val hstatus   = Input(new HstatusBundle)
32237d4cfdSXuan Hu  val vsstatus  = Input(new SstatusBundle)
33237d4cfdSXuan Hu  val sepc      = Input(new Epc())
34237d4cfdSXuan Hu  val vsepc     = Input(new Epc())
35c1b28b66STang Haojin  val satp      = Input(new SatpBundle)
36c1b28b66STang Haojin  val vsatp     = Input(new SatpBundle)
37c1b28b66STang Haojin  val hgatp     = Input(new HgatpBundle)
38237d4cfdSXuan Hu}
39237d4cfdSXuan Hu
40c1b28b66STang Haojinclass SretEventModule(implicit p: Parameters) extends Module with CSREventBase {
41237d4cfdSXuan Hu  val in = IO(new SretEventInput)
42237d4cfdSXuan Hu  val out = IO(new SretEventOutput)
43237d4cfdSXuan Hu
44*eca6983fSZehao Liu  val outSDT = IO(new SretEventSDTOutput)
45*eca6983fSZehao Liu
46c1b28b66STang Haojin  private val satp = in.satp
47c1b28b66STang Haojin  private val vsatp = in.vsatp
48c1b28b66STang Haojin  private val hgatp = in.hgatp
49c1b28b66STang Haojin  private val nextPrivState = out.privState.bits
50c1b28b66STang Haojin
51c1b28b66STang Haojin  private val instrAddrTransType = AddrTransType(
52c1b28b66STang Haojin    bare = (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) ||
53c1b28b66STang Haojin           (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare),
54c1b28b66STang Haojin    sv39 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 ||
55c1b28b66STang Haojin           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39,
56c1b28b66STang Haojin    sv48 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 ||
57c1b28b66STang Haojin           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48,
58c1b28b66STang Haojin    sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4,
59c1b28b66STang Haojin    sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
60c1b28b66STang Haojin  )
61c1b28b66STang Haojin
626808b803SZehao Liu  private val sretInM     = in.privState.isModeM
636808b803SZehao Liu  private val sretInHS    = in.privState.isModeHS
646808b803SZehao Liu  private val sretInHSorM = sretInM || sretInHS
65c1b28b66STang Haojin  private val sretInVS    = in.privState.isModeVS
66c1b28b66STang Haojin
67c1b28b66STang Haojin  private val xepc = Mux1H(Seq(
68c1b28b66STang Haojin    sretInHSorM -> in.sepc,
69c1b28b66STang Haojin    sretInVS    -> in.vsepc,
70c1b28b66STang Haojin  )).asUInt
71237d4cfdSXuan Hu
726808b803SZehao Liu
736808b803SZehao Liu  private val outPrivState   = Wire(new PrivState)
746808b803SZehao Liu  outPrivState.PRVM := Mux1H(Seq(
756808b803SZehao Liu    // SPP is not PrivMode enum type, so asUInt
766808b803SZehao Liu    sretInHSorM -> in.mstatus.SPP.asUInt,
776808b803SZehao Liu    sretInVS    -> in.vsstatus.SPP.asUInt,
786808b803SZehao Liu  ))
796808b803SZehao Liu  outPrivState.V := Mux1H(Seq(
806808b803SZehao Liu    sretInHSorM -> in.hstatus.SPV,
816808b803SZehao Liu    sretInVS    -> in.privState.V, // keep
826808b803SZehao Liu  ))
836808b803SZehao Liu
846808b803SZehao Liu  private val sretToVU    = outPrivState.isModeVU
856808b803SZehao Liu  private val sretToVS    = outPrivState.isModeVS
866808b803SZehao Liu  private val sretToU     = outPrivState.isModeHU
876808b803SZehao Liu
88237d4cfdSXuan Hu  out := DontCare
89*eca6983fSZehao Liu  outSDT := DontCare
90237d4cfdSXuan Hu
91237d4cfdSXuan Hu  out.privState.valid := valid
92237d4cfdSXuan Hu  out.targetPc .valid := valid
93237d4cfdSXuan Hu
946808b803SZehao Liu  out.privState.bits      := outPrivState
95237d4cfdSXuan Hu
96237d4cfdSXuan Hu  // hstatus
97237d4cfdSXuan Hu  out.hstatus.valid           := valid && sretInHSorM
98237d4cfdSXuan Hu  out.hstatus.bits.SPV        := VirtMode.Off
99237d4cfdSXuan Hu
100237d4cfdSXuan Hu  // sstatus
101237d4cfdSXuan Hu  out.mstatus.valid           := valid && sretInHSorM
102237d4cfdSXuan Hu  out.mstatus.bits.SPP        := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
1036808b803SZehao Liu  out.mstatus.bits.SIE        := in.mstatus.SPIE
104237d4cfdSXuan Hu  out.mstatus.bits.SPIE       := 1.U
105237d4cfdSXuan Hu  out.mstatus.bits.MPRV       := 0.U // sret will always leave M mode
1066808b803SZehao Liu  out.mstatus.bits.MDT        := Mux(sretInM, 0.U, in.mstatus.MDT.asBool) // when execute return in M mode, set MDT 0
1076808b803SZehao Liu  out.mstatus.bits.SDT        := MuxCase(in.mstatus.SDT.asBool, Seq(
1086808b803SZehao Liu    sretInHS   -> 0.U, // sret will alway leave M mode
1096808b803SZehao Liu    (sretInM && (sretToU || sretToVS || sretToVU))    -> 0.U
1106808b803SZehao Liu  ))
1116808b803SZehao Liu
112237d4cfdSXuan Hu
113237d4cfdSXuan Hu  // vsstatus
114237d4cfdSXuan Hu  out.vsstatus.valid          := valid && sretInVS
115237d4cfdSXuan Hu  out.vsstatus.bits.SPP       := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
116237d4cfdSXuan Hu  out.vsstatus.bits.SIE       := in.vsstatus.SPIE
117237d4cfdSXuan Hu  out.vsstatus.bits.SPIE      := 1.U
118*eca6983fSZehao Liu
119*eca6983fSZehao Liu  outSDT.vsstatus.valid       := valid && (sretToVU || sretInVS) // clear SDT when return to VU or sret in vs
120*eca6983fSZehao Liu  outSDT.vsstatus.bits.SDT    := 0.U
121237d4cfdSXuan Hu
122c1b28b66STang Haojin  out.targetPc.bits.pc        := xepc
123c1b28b66STang Haojin  out.targetPc.bits.raiseIPF  := instrAddrTransType.checkPageFault(xepc)
124c1b28b66STang Haojin  out.targetPc.bits.raiseIAF  := instrAddrTransType.checkAccessFault(xepc)
125c1b28b66STang Haojin  out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc)
126237d4cfdSXuan Hu
127237d4cfdSXuan Hu  // for better verilog
128237d4cfdSXuan Hu  dontTouch(sretInHSorM)
129237d4cfdSXuan Hu  dontTouch(sretInVS)
130237d4cfdSXuan Hu}
131237d4cfdSXuan Hu
132cb36ac0fSXuan Hutrait SretEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] =>
133237d4cfdSXuan Hu  val retFromS = IO(Flipped(new SretEventOutput))
134237d4cfdSXuan Hu
135cb36ac0fSXuan Hu  addUpdateBundleInCSREnumType(retFromS.getBundleByName(self.modName.toLowerCase()))
136237d4cfdSXuan Hu
137cb36ac0fSXuan Hu  reconnectReg()
138237d4cfdSXuan Hu}
139*eca6983fSZehao Liu
140*eca6983fSZehao Liutrait SretEventSDTSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] =>
141*eca6983fSZehao Liu  val retFromSSDT = IO(Flipped(new SretEventSDTOutput))
142*eca6983fSZehao Liu
143*eca6983fSZehao Liu  addUpdateBundleInCSREnumType(retFromSSDT.getBundleByName(self.modName.toLowerCase()))
144*eca6983fSZehao Liu
145*eca6983fSZehao Liu  reconnectReg()
146*eca6983fSZehao Liu}
147*eca6983fSZehao Liu
148