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