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}