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.NewCSR.CSRBundleImplicitCast._ 9 10 11class TrapHandleModule extends Module { 12 val io = IO(new TrapHandleIO) 13 14 private val trapInfo = io.in.trapInfo 15 private val privState = io.in.privState 16 private val mideleg = io.in.mideleg.asUInt 17 private val hideleg = io.in.hideleg.asUInt 18 private val medeleg = io.in.medeleg.asUInt 19 private val hedeleg = io.in.hedeleg.asUInt 20 21 private val hasTrap = trapInfo.valid 22 private val hasIR = hasTrap && trapInfo.bits.isInterrupt 23 private val hasEX = hasTrap && !trapInfo.bits.isInterrupt 24 25 private val exceptionVec = io.in.trapInfo.bits.trapVec 26 private val intrVec = io.in.trapInfo.bits.intrVec 27 private val hasEXVec = Mux(hasEX, exceptionVec, 0.U) 28 private val hasIRVec = Mux(hasIR, intrVec, 0.U) 29 30 private val highestPrioIRVec = Wire(Vec(64, Bool())) 31 highestPrioIRVec.zipWithIndex.foreach { case (irq, i) => 32 if (InterruptNO.interruptDefaultPrio.contains(i)) { 33 val higherIRSeq = InterruptNO.getIRQHigherThan(i) 34 irq := ( 35 higherIRSeq.nonEmpty.B && Cat(higherIRSeq.map(num => !hasIRVec(num))).andR || 36 higherIRSeq.isEmpty.B 37 ) && hasIRVec(i) 38 dontTouch(irq) 39 } else 40 irq := false.B 41 } 42 43 private val highestPrioEXVec = Wire(Vec(64, Bool())) 44 highestPrioEXVec.zipWithIndex.foreach { case (excp, i) => 45 if (ExceptionNO.priorities.contains(i)) { 46 val higherEXSeq = ExceptionNO.getHigherExcpThan(i) 47 excp := ( 48 higherEXSeq.nonEmpty.B && Cat(higherEXSeq.map(num => !hasEXVec(num))).andR || 49 higherEXSeq.isEmpty.B 50 ) && hasEXVec(i) 51 } else 52 excp := false.B 53 } 54 55 private val highestPrioIR = highestPrioIRVec.asUInt 56 private val highestPrioEX = highestPrioEXVec.asUInt 57 58 private val mIRVec = highestPrioIR 59 private val hsIRVec = highestPrioIR & mideleg 60 private val vsIRVec = highestPrioIR & mideleg & hideleg 61 62 private val mEXVec = highestPrioEX 63 private val hsEXVec = highestPrioEX & medeleg 64 private val vsEXVec = highestPrioEX & medeleg & hedeleg 65 66 private val mHasIR = mIRVec.orR 67 private val hsHasIR = hsIRVec.orR 68 private val vsHasIR = vsIRVec.orR 69 70 private val mHasEX = mEXVec.orR 71 private val hsHasEX = hsEXVec.orR 72 private val vsHasEX = vsEXVec.orR 73 74 private val mHasTrap = mHasEX || mHasIR 75 private val hsHasTrap = hsHasEX || hsHasIR 76 private val vsHasTrap = vsHasEX || vsHasIR 77 78 private val handleTrapUnderHS = !privState.isModeM && hsHasTrap 79 private val handleTrapUnderVS = privState.isVirtual && vsHasTrap 80 81 // Todo: support more interrupt and exception 82 private val exceptionRegular = OHToUInt(highestPrioEX) 83 private val interruptNO = OHToUInt(highestPrioIR) 84 private val exceptionNO = Mux(trapInfo.bits.singleStep || trapInfo.bits.triggerFire, ExceptionNO.breakPoint.U, exceptionRegular) 85 86 private val causeNO = Mux(hasIR, interruptNO, exceptionNO) 87 88 private val xtvec = MuxCase(io.in.mtvec, Seq( 89 handleTrapUnderVS -> io.in.vstvec, 90 handleTrapUnderHS -> io.in.stvec 91 )) 92 private val pcFromXtvec = Cat(xtvec.addr.asUInt + Mux(xtvec.mode === XtvecMode.Vectored && hasIR, interruptNO(5, 0), 0.U), 0.U(2.W)) 93 94 io.out.entryPrivState := MuxCase(default = PrivState.ModeM, mapping = Seq( 95 handleTrapUnderVS -> PrivState.ModeVS, 96 handleTrapUnderHS -> PrivState.ModeHS, 97 )) 98 99 io.out.causeNO.Interrupt := hasIR 100 io.out.causeNO.ExceptionCode := causeNO 101 io.out.pcFromXtvec := pcFromXtvec 102} 103 104class TrapHandleIO extends Bundle { 105 val in = Input(new Bundle { 106 val trapInfo = ValidIO(new Bundle { 107 val trapVec = UInt(64.W) 108 val intrVec = UInt(64.W) 109 val isInterrupt = Bool() 110 val singleStep = Bool() 111 val triggerFire = Bool() 112 }) 113 val privState = new PrivState 114 val mideleg = new MidelegBundle 115 val medeleg = new MedelegBundle 116 val hideleg = new HidelegBundle 117 val hedeleg = new HedelegBundle 118 // trap vector 119 val mtvec = Input(new XtvecBundle) 120 val stvec = Input(new XtvecBundle) 121 val vstvec = Input(new XtvecBundle) 122 }) 123 124 val out = new Bundle { 125 val entryPrivState = new PrivState 126 val causeNO = new CauseBundle 127 val pcFromXtvec = UInt() 128 } 129}