xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapHandleModule.scala (revision a7a6d0a6adb97825acea8ab65b97b616782d63de)
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 exceptionVec = io.in.trapInfo.bits.trapVec
21  private val intrVec = io.in.trapInfo.bits.intrVec
22  private val hasEXVec = Mux(hasEX, exceptionVec, 0.U)
23  private val hasIRVec = Mux(hasIR, intrVec, 0.U)
24
25  // Todo: support more interrupt and exception
26  private val exceptionRegular = 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  private val exceptionNO = Mux(trapInfo.bits.singleStep || trapInfo.bits.triggerFire, ExceptionNO.breakPoint.U, exceptionRegular)
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      val singleStep = Bool()
60      val triggerFire = Bool()
61    })
62    val privState = new PrivState
63    val mideleg = new MidelegBundle
64    val medeleg = new MedelegBundle
65    val hideleg = new HidelegBundle
66    val hedeleg = new HedelegBundle
67    // trap vector
68    val mtvec = Input(new XtvecBundle)
69    val stvec = Input(new XtvecBundle)
70    val vstvec = Input(new XtvecBundle)
71  })
72
73  val out = new Bundle {
74    val entryPrivState = new PrivState
75    val causeNO = new CauseBundle
76    val pcFromXtvec = UInt()
77  }
78}