xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapHandleModule.scala (revision 25dc4a827ee27e3ccbaf02e8e5134872cba28fcd)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import xiangshan.ExceptionNO
6import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, PrivState, XtvecBundle}
7import xiangshan.backend.fu.NewCSR.CSRDefines.XtvecMode
8import xiangshan.backend.fu.util.CSRConst
9
10class TrapHandleModule extends Module {
11  val io = IO(new TrapHandleIO)
12
13  private val trapInfo = io.in.trapInfo
14  private val privState = io.in.privState
15
16  private val hasTrap = trapInfo.valid
17  private val hasIR = hasTrap && trapInfo.bits.isInterrupt
18  private val hasEX = hasTrap && !trapInfo.bits.isInterrupt
19
20  private val trapVec = io.in.trapInfo.bits.trapVec
21  private val hasEXVec = Mux(hasEX, trapVec, 0.U)
22  private val hasIRVec = Mux(hasIR, trapVec, 0.U)
23
24  // Todo: support more interrupt and exception
25  private val exceptionNO = ExceptionNO.priorities.foldRight(0.U(6.W))((i: Int, sum: UInt) => Mux(hasEXVec(i), i.U, sum))
26  private val interruptNO = CSRConst.IntPriority.foldRight(0.U(6.W))((i: Int, sum: UInt) => Mux(hasIRVec(i), i.U, sum))
27
28  private val causeNO = Mux(hasIR, interruptNO, exceptionNO)
29
30  private val mdeleg = Mux(hasIR, io.in.mideleg.asUInt, io.in.medeleg.asUInt)
31  private val hdeleg = Mux(hasIR, io.in.hideleg.asUInt, io.in.hedeleg.asUInt)
32
33  private val handleTrapUnderHS = mdeleg(causeNO) && privState < PrivState.ModeM
34  private val handleTrapUnderVS = mdeleg(causeNO) && hdeleg(causeNO) && privState < PrivState.ModeHS
35
36  private val xtvec = MuxCase(io.in.mtvec, Seq(
37    handleTrapUnderVS -> io.in.vstvec,
38    handleTrapUnderHS -> io.in.stvec
39  ))
40  private val pcFromXtvec = Cat(xtvec.addr.asUInt + Mux(io.in.mtvec.mode === XtvecMode.Vectored && hasIR, interruptNO(5, 0), 0.U), 0.U(2.W))
41
42  io.out.entryPrivState := MuxCase(default = PrivState.ModeM, mapping = Seq(
43    handleTrapUnderVS -> PrivState.ModeVS,
44    handleTrapUnderHS -> PrivState.ModeHS,
45  ))
46
47  io.out.causeNO.Interrupt := hasIR
48  io.out.causeNO.ExceptionCode := causeNO
49  io.out.pcFromXtvec := pcFromXtvec
50}
51
52class TrapHandleIO extends Bundle {
53  val in = Input(new Bundle {
54    val trapInfo = ValidIO(new Bundle {
55      val trapVec = UInt(64.W)
56      val isInterrupt = Bool()
57    })
58    val privState = new PrivState
59    val mideleg = new MidelegBundle
60    val medeleg = new MedelegBundle
61    val hideleg = new HidelegBundle
62    val hedeleg = new HedelegBundle
63    // trap vector
64    val mtvec = Input(new XtvecBundle)
65    val stvec = Input(new XtvecBundle)
66    val vstvec = Input(new XtvecBundle)
67  })
68
69  val out = new Bundle {
70    val entryPrivState = new PrivState
71    val causeNO = new CauseBundle
72    val pcFromXtvec = UInt()
73  }
74}