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 Epc ).addInEvent(_.epc)) 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 iMode = current.iMode 47 private val satp = current.satp 48 private val vsatp = current.vsatp 49 private val hgatp = current.hgatp 50 51 private val hasTrap = in.hasTrap 52 private val debugMode = in.debugMode 53 private val hasDebugIntr = in.hasDebugIntr 54 private val breakPoint = in.breakPoint 55 private val hasTriggerFire = in.hasTriggerFire 56 private val hasDebugEbreakException = in.hasDebugEbreakException 57 private val hasSingleStep = in.hasSingleStep 58 59 private val hasExceptionInDmode = debugMode && hasTrap 60 val causeIntr = DcsrCause.Haltreq.asUInt 61 val causeExp = MuxCase(0.U, Seq( 62 hasTriggerFire -> DcsrCause.Trigger.asUInt, 63 hasDebugEbreakException -> DcsrCause.Ebreak.asUInt, 64 hasSingleStep -> DcsrCause.Step.asUInt 65 )) 66 67 private val trapPC = genTrapVA( 68 iMode, 69 satp, 70 vsatp, 71 hgatp, 72 in.trapPc, 73 ) 74 75 // ebreak jump debugEntry not debugException in dmode 76 // debug rom make hart write 0 to DebugMMIO.EXCEPTION when exception happened in debugMode. 77 // let debug module known hart got an exception. 78 // note: Need't know exception number in debugMode. 79 // exception(EX_BP) must be ebreak here! 80 val debugPc = Mux(hasExceptionInDmode && !breakPoint, DebugException.U, DebugEntry.U) 81 82 out := DontCare 83 // output 84 out.dcsr.valid := valid 85 out.dpc.valid := valid 86 // !debugMode trap || debugMode hasExp 87 out.targetPc.valid := valid || hasExceptionInDmode 88 out.debugMode.valid := valid 89 out.privState.valid := valid 90 out.debugIntrEnable.valid := valid 91 92 out.dcsr.bits.V := current.privState.V.asUInt 93 out.dcsr.bits.PRV := current.privState.PRVM.asUInt 94 out.dcsr.bits.CAUSE := Mux(hasDebugIntr, causeIntr, causeExp) 95 out.dpc.bits.epc := trapPC(VaddrMaxWidth - 1, 1) 96 97 out.targetPc.bits := debugPc 98 out.debugMode.bits := true.B 99 out.privState.bits := PrivState.ModeM 100 out.debugIntrEnable.bits := false.B 101 102} 103 104trait TrapEntryDEventSinkBundle { self: CSRModule[_] => 105 val trapToD = IO(Flipped(new TrapEntryDEventOutput)) 106 107 private val updateBundle: ValidIO[CSRBundle] = trapToD.getBundleByName(self.modName.toLowerCase()) 108 109 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 110 if (updateBundle.bits.eventFields.contains(source)) { 111 when(updateBundle.valid) { 112 sink := source 113 } 114 } 115 } 116} 117