1package xiangshan.backend.fu.NewCSR.CSREvents 2 3import chisel3._ 4import chisel3.util.{MuxCase, _} 5import org.chipsalliance.cde.config.Parameters 6import utility.{SignExt, ZeroExt} 7import xiangshan.{ExceptionNO, HasXSParameter, TriggerCf} 8import xiangshan.ExceptionNO._ 9import xiangshan.backend.fu.NewCSR 10import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 11import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 12import xiangshan.backend.fu.NewCSR.CSRDefines.SatpMode 13import xiangshan.backend.fu.NewCSR._ 14 15 16class TrapEntryDEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 17 val dcsr = ValidIO((new DcsrBundle).addInEvent(_.CAUSE, _.V, _.PRV)) 18 val dpc = ValidIO((new Dpc ).addInEvent(_.ALL)) 19 val targetPc = ValidIO(UInt(VaddrMaxWidth.W)) 20 val debugMode = ValidIO(Bool()) 21 val debugIntrEnable = ValidIO(Bool()) 22 23 def getBundleByName(name: String): Valid[CSRBundle] = { 24 name match { 25 case "dcsr" => this.dcsr 26 case "dpc" => this.dpc 27 } 28 } 29} 30 31class TrapEntryDEventInput(implicit override val p: Parameters) extends TrapEntryEventInput{ 32 val hasTrap = Input(Bool()) 33 val debugMode = Input(Bool()) 34 val hasDebugIntr = Input(Bool()) 35 val hasTriggerFire = Input(Bool()) 36 val hasDebugEbreakException = Input(Bool()) 37 val hasSingleStep = Input(Bool()) 38 val breakPoint = Input(Bool()) 39} 40 41class TrapEntryDEventModule(implicit val p: Parameters) extends Module with CSREventBase with DebugMMIO { 42 val in = IO(new TrapEntryDEventInput) 43 val out = IO(new TrapEntryDEventOutput) 44 45 private val current = in 46 private val hasTrap = in.hasTrap 47 private val debugMode = in.debugMode 48 private val hasDebugIntr = in.hasDebugIntr 49 private val breakPoint = in.breakPoint 50 private val hasTriggerFire = in.hasTriggerFire 51 private val hasDebugEbreakException = in.hasDebugEbreakException 52 private val hasSingleStep = in.hasSingleStep 53 54 private val hasExceptionInDmode = debugMode && hasTrap 55 val causeIntr = DcsrCause.Haltreq.asUInt 56 val causeExp = MuxCase(0.U, Seq( 57 hasTriggerFire -> DcsrCause.Trigger.asUInt, 58 hasDebugEbreakException -> DcsrCause.Ebreak.asUInt, 59 hasSingleStep -> DcsrCause.Step.asUInt 60 )) 61 62 private val trapPC = Wire(UInt(XLEN.W)) 63 private val ivmHS = !current.iMode.isModeHS && current.satp.MODE =/= SatpMode.Bare 64 private val ivmVS = !current.iMode.isModeVS && current.vsatp.MODE =/= SatpMode.Bare 65 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 66 trapPC := Mux(ivmHS || ivmVS, SignExt(in.trapPc, XLEN), ZeroExt(in.trapPc, XLEN)) 67 68 // ebreak jump debugEntry not debugException in dmode 69 // debug rom make hart write 0 to DebugMMIO.EXCEPTION when exception happened in debugMode. 70 // let debug module known hart got an exception. 71 // note: Need't know exception number in debugMode. 72 // exception(EX_BP) must be ebreak here! 73 val debugPc = Mux(hasExceptionInDmode && !breakPoint, DebugException.U, DebugEntry.U) 74 75 out := DontCare 76 // output 77 out.dcsr.valid := valid 78 out.dpc.valid := valid 79 // !debugMode trap || debugMode hasExp 80 out.targetPc.valid := valid || hasExceptionInDmode 81 out.debugMode.valid := valid 82 out.privState.valid := valid 83 out.debugIntrEnable.valid := valid 84 85 out.dcsr.bits.V := current.privState.V.asUInt 86 out.dcsr.bits.PRV := current.privState.PRVM.asUInt 87 out.dcsr.bits.CAUSE := Mux(hasDebugIntr, causeIntr, causeExp) 88 out.dpc.bits := trapPC 89 90 out.targetPc.bits := debugPc 91 out.debugMode.bits := true.B 92 out.privState.bits := PrivState.ModeM 93 out.debugIntrEnable.bits := false.B 94 95} 96 97trait TrapEntryDEventSinkBundle { self: CSRModule[_] => 98 val trapToD = IO(Flipped(new TrapEntryDEventOutput)) 99 100 private val updateBundle: ValidIO[CSRBundle] = trapToD.getBundleByName(self.modName.toLowerCase()) 101 102 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 103 if (updateBundle.bits.eventFields.contains(source)) { 104 when(updateBundle.valid) { 105 sink := source 106 } 107 } 108 } 109} 110