xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapHandleModule.scala (revision bcc5f81fc420baefe606470c3ab8c8ce14bbfaa4)
1dafddbf0SXuan Hupackage xiangshan.backend.fu.NewCSR
2dafddbf0SXuan Hu
3dafddbf0SXuan Huimport chisel3._
4dafddbf0SXuan Huimport chisel3.util._
5dafddbf0SXuan Huimport xiangshan.ExceptionNO
60c2ba7aeSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, PrivState, XtvecBundle}
70c2ba7aeSXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.XtvecMode
873e616deSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._
973e616deSXuan Hu
10dafddbf0SXuan Hu
11dafddbf0SXuan Huclass TrapHandleModule extends Module {
12dafddbf0SXuan Hu  val io = IO(new TrapHandleIO)
13dafddbf0SXuan Hu
14dafddbf0SXuan Hu  private val trapInfo = io.in.trapInfo
15dafddbf0SXuan Hu  private val privState = io.in.privState
166808b803SZehao Liu  private val mstatus  = io.in.mstatus
176808b803SZehao Liu  private val vsstatus = io.in.vsstatus
186808b803SZehao Liu  private val mnstatus = io.in.mnstatus
1973e616deSXuan Hu  private val mideleg = io.in.mideleg.asUInt
2073e616deSXuan Hu  private val hideleg = io.in.hideleg.asUInt
2173e616deSXuan Hu  private val medeleg = io.in.medeleg.asUInt
2273e616deSXuan Hu  private val hedeleg = io.in.hedeleg.asUInt
23a3dd7166SXuan Hu  private val mvien = io.in.mvien.asUInt
24a3dd7166SXuan Hu  private val hvien = io.in.hvien.asUInt
259205730dSsinceforYy  private val virtualInterruptIsHvictlInject = io.in.virtualInterruptIsHvictlInject
26dafddbf0SXuan Hu
27dafddbf0SXuan Hu  private val hasTrap = trapInfo.valid
28c2a2229dSlewislzh  private val hasNMI = hasTrap && trapInfo.bits.nmi
29dafddbf0SXuan Hu  private val hasIR = hasTrap && trapInfo.bits.isInterrupt
30dafddbf0SXuan Hu  private val hasEX = hasTrap && !trapInfo.bits.isInterrupt
31dafddbf0SXuan Hu
32a7a6d0a6Schengguanghui  private val exceptionVec = io.in.trapInfo.bits.trapVec
33d5f305ceSsinceforYy  private val intrVec = io.in.trapInfo.bits.intrVec
34a7a6d0a6Schengguanghui  private val hasEXVec = Mux(hasEX, exceptionVec, 0.U)
35d5f305ceSsinceforYy  private val hasIRVec = Mux(hasIR, intrVec, 0.U)
36dafddbf0SXuan Hu
37a5cb9e82SsinceforYy  private val irToHS = io.in.trapInfo.bits.irToHS
38a5cb9e82SsinceforYy  private val irToVS = io.in.trapInfo.bits.irToVS
39a5cb9e82SsinceforYy
4073e616deSXuan Hu  private val highestPrioEXVec = Wire(Vec(64, Bool()))
4173e616deSXuan Hu  highestPrioEXVec.zipWithIndex.foreach { case (excp, i) =>
4273e616deSXuan Hu    if (ExceptionNO.priorities.contains(i)) {
4369de61beSXuan Hu      val higherEXSeq = ExceptionNO.getHigherExcpThan(i)
4469de61beSXuan Hu      excp := (
4569de61beSXuan Hu        higherEXSeq.nonEmpty.B && Cat(higherEXSeq.map(num => !hasEXVec(num))).andR ||
4669de61beSXuan Hu        higherEXSeq.isEmpty.B
4769de61beSXuan Hu      ) && hasEXVec(i)
4873e616deSXuan Hu    } else
4973e616deSXuan Hu      excp := false.B
5073e616deSXuan Hu  }
5173e616deSXuan Hu
523113cca9SsinceforYy  private val highestPrioIR  = hasIRVec.asUInt
5373e616deSXuan Hu  private val highestPrioEX  = highestPrioEXVec.asUInt
5473e616deSXuan Hu
5573e616deSXuan Hu  private val mEXVec  = highestPrioEX
5673e616deSXuan Hu  private val hsEXVec = highestPrioEX & medeleg
5773e616deSXuan Hu  private val vsEXVec = highestPrioEX & medeleg & hedeleg
5873e616deSXuan Hu
59c2a2229dSlewislzh  // nmi handle in MMode only and default handler is mtvec
60a5cb9e82SsinceforYy  private val  mHasIR = hasIR
61a5cb9e82SsinceforYy  private val hsHasIR = hasIR && irToHS & !hasNMI
62a5cb9e82SsinceforYy  private val vsHasIR = hasIR && irToVS & !hasNMI
6373e616deSXuan Hu
6473e616deSXuan Hu  private val  mHasEX =  mEXVec.orR
6573e616deSXuan Hu  private val hsHasEX = hsEXVec.orR
6673e616deSXuan Hu  private val vsHasEX = vsEXVec.orR
6773e616deSXuan Hu
6873e616deSXuan Hu  private val  mHasTrap =  mHasEX ||  mHasIR
6973e616deSXuan Hu  private val hsHasTrap = hsHasEX || hsHasIR
7073e616deSXuan Hu  private val vsHasTrap = vsHasEX || vsHasIR
7173e616deSXuan Hu
7273e616deSXuan Hu  private val handleTrapUnderHS = !privState.isModeM && hsHasTrap
7373e616deSXuan Hu  private val handleTrapUnderVS = privState.isVirtual && vsHasTrap
746808b803SZehao Liu  private val handleTrapUnderM = !handleTrapUnderVS && !handleTrapUnderHS
7573e616deSXuan Hu
76dafddbf0SXuan Hu  // Todo: support more interrupt and exception
7773e616deSXuan Hu  private val exceptionRegular = OHToUInt(highestPrioEX)
7822872cfdSsinceforYy  private val interruptNO = highestPrioIR
797e0f64b0SGuanghui Cheng  private val exceptionNO = Mux(trapInfo.bits.singleStep, ExceptionNO.breakPoint.U, exceptionRegular)
8073e616deSXuan Hu
81dafddbf0SXuan Hu  private val causeNO = Mux(hasIR, interruptNO, exceptionNO)
82dafddbf0SXuan Hu
836808b803SZehao Liu  // sm/ssdbltrp
846808b803SZehao Liu  private val m_EX_DT  = handleTrapUnderM  && mstatus.MDT.asBool  && hasTrap
856808b803SZehao Liu  private val s_EX_DT  = handleTrapUnderHS && mstatus.SDT.asBool  && hasTrap
866808b803SZehao Liu  private val vs_EX_DT = handleTrapUnderVS && vsstatus.SDT.asBool && hasTrap
876808b803SZehao Liu
886808b803SZehao Liu  private val dbltrpToMN = m_EX_DT && mnstatus.NMIE.asBool // NMI not allow double trap
896808b803SZehao Liu  private val hasDTExcp  = m_EX_DT || s_EX_DT || vs_EX_DT
906808b803SZehao Liu
916808b803SZehao Liu  private val trapToHS = handleTrapUnderHS && !s_EX_DT && !vs_EX_DT
926808b803SZehao Liu  private val traptoVS = handleTrapUnderVS && !vs_EX_DT
936808b803SZehao Liu
940c2ba7aeSXuan Hu  private val xtvec = MuxCase(io.in.mtvec, Seq(
956808b803SZehao Liu    traptoVS -> io.in.vstvec,
966808b803SZehao Liu    trapToHS -> io.in.stvec
970c2ba7aeSXuan Hu  ))
9874fd4f59SZehao Liu  private val adjustinterruptNO = Mux(
9974fd4f59SZehao Liu    InterruptNO.getVS.map(_.U === interruptNO).reduce(_ || _) && vsHasIR,
10074fd4f59SZehao Liu    interruptNO - 1.U, // map VSSIP, VSTIP, VSEIP to SSIP, STIP, SEIP
10174fd4f59SZehao Liu    interruptNO,
10274fd4f59SZehao Liu  )
10374fd4f59SZehao Liu  private val pcFromXtvec = Cat(xtvec.addr.asUInt + Mux(xtvec.mode === XtvecMode.Vectored && hasIR, adjustinterruptNO(5, 0), 0.U), 0.U(2.W))
1040c2ba7aeSXuan Hu
105dafddbf0SXuan Hu  io.out.entryPrivState := MuxCase(default = PrivState.ModeM, mapping = Seq(
1066808b803SZehao Liu    traptoVS -> PrivState.ModeVS,
1076808b803SZehao Liu    trapToHS -> PrivState.ModeHS,
108dafddbf0SXuan Hu  ))
109dafddbf0SXuan Hu
110dafddbf0SXuan Hu  io.out.causeNO.Interrupt := hasIR
111dafddbf0SXuan Hu  io.out.causeNO.ExceptionCode := causeNO
1120c2ba7aeSXuan Hu  io.out.pcFromXtvec := pcFromXtvec
1136808b803SZehao Liu  io.out.hasDTExcp := hasDTExcp
1146808b803SZehao Liu  io.out.dbltrpToMN := dbltrpToMN
1153174481bSXuan Hu
116dafddbf0SXuan Hu}
117dafddbf0SXuan Hu
118dafddbf0SXuan Huclass TrapHandleIO extends Bundle {
119dafddbf0SXuan Hu  val in = Input(new Bundle {
120dafddbf0SXuan Hu    val trapInfo = ValidIO(new Bundle {
121dafddbf0SXuan Hu      val trapVec = UInt(64.W)
122c2a2229dSlewislzh      val nmi = Bool()
12322872cfdSsinceforYy      val intrVec = UInt(8.W)
124dafddbf0SXuan Hu      val isInterrupt = Bool()
125a7a6d0a6Schengguanghui      val singleStep = Bool()
126a5cb9e82SsinceforYy      // trap to x mode
127a5cb9e82SsinceforYy      val irToHS = Bool()
128a5cb9e82SsinceforYy      val irToVS = Bool()
129dafddbf0SXuan Hu    })
130dafddbf0SXuan Hu    val privState = new PrivState
1316808b803SZehao Liu    val mstatus = new MstatusBundle
1326808b803SZehao Liu    val vsstatus = new SstatusBundle
1336808b803SZehao Liu    val mnstatus = new MnstatusBundle
134dafddbf0SXuan Hu    val mideleg = new MidelegBundle
135dafddbf0SXuan Hu    val medeleg = new MedelegBundle
136dafddbf0SXuan Hu    val hideleg = new HidelegBundle
137dafddbf0SXuan Hu    val hedeleg = new HedelegBundle
138a3dd7166SXuan Hu    val mvien = new MvienBundle
139a3dd7166SXuan Hu    val hvien = new HvienBundle
1400c2ba7aeSXuan Hu    // trap vector
1410c2ba7aeSXuan Hu    val mtvec = Input(new XtvecBundle)
1420c2ba7aeSXuan Hu    val stvec = Input(new XtvecBundle)
1430c2ba7aeSXuan Hu    val vstvec = Input(new XtvecBundle)
1449205730dSsinceforYy    // virtual interrupt is hvictl inject
1459205730dSsinceforYy    val virtualInterruptIsHvictlInject = Input(Bool())
146dafddbf0SXuan Hu  })
147dafddbf0SXuan Hu
148dafddbf0SXuan Hu  val out = new Bundle {
149dafddbf0SXuan Hu    val entryPrivState = new PrivState
150dafddbf0SXuan Hu    val causeNO = new CauseBundle
1516808b803SZehao Liu    val dbltrpToMN = Bool()
1526808b803SZehao Liu    val hasDTExcp = Bool()
153*bcc5f81fSZhaoyang You    val pcFromXtvec = UInt(64.W)
154dafddbf0SXuan Hu  }
155dafddbf0SXuan Hu}
156