1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6 7import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState 8import xiangshan.backend.fu.util.CSRConst 9import xiangshan._ 10 11class Debug(implicit val p: Parameters) extends Module with HasXSParameter { 12 val io = IO(new DebugIO) 13 14 private val trapInfo = io.in.trapInfo 15 private val hasTrap = trapInfo.valid 16 private val trapIsInterrupt = trapInfo.bits.isInterrupt 17 private val intrVec = trapInfo.bits.intrVec 18 private val trapVec = trapInfo.bits.trapVec 19 private val singleStep = trapInfo.bits.singleStep 20 private val triggerCf = io.in.trapInfo.bits.triggerCf 21 22 private val privState = io.in.privState 23 private val debugMode = io.in.debugMode 24 25 private val dcsr = io.in.dcsr 26 private val tcontrol = io.in.tcontrol 27 private val tselect = io.in.tselect 28 private val tdata1Selected = io.in.tdata1Selected 29 private val tdata2Selected = io.in.tdata2Selected 30 private val tdata1Vec = io.in.tdata1Vec 31 32 private val tdata1Update = io.in.tdata1Update 33 private val tdata2Update = io.in.tdata2Update 34 private val tdata1Wdata = io.in.tdata1Wdata 35 36 /** 37 * ways to entry Dmode: 38 * 1. debug intr(from external debug module) 39 * 2. ebreak inst in nonDmode 40 * 3. trigger fire in nonDmode 41 * 4. single step(debug module set dcsr.step before hart resume) 42 */ 43 // debug_intr 44 val hasIntr = hasTrap && trapIsInterrupt 45 val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG) 46 47 // debug_exception_ebreak 48 val hasExp = hasTrap && !trapIsInterrupt 49 val breakPoint = trapVec(ExceptionNO.breakPoint).asBool 50 val hasBreakPoint = hasExp && breakPoint 51 val ebreakEnterDebugMode = 52 (privState.isModeM && dcsr.EBREAKM.asBool) || 53 (privState.isModeHS && dcsr.EBREAKS.asBool) || 54 (privState.isModeHU && dcsr.EBREAKU.asBool) || 55 (privState.isModeVS && dcsr.EBREAKVS.asBool) || 56 (privState.isModeVU && dcsr.EBREAKVU.asBool) 57 val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 58 59 // debug_exception_trigger 60 val triggerFrontendHitVec = triggerCf.frontendHit 61 val triggerMemHitVec = triggerCf.backendHit 62 val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit 63 val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt 64 val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt 65 val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec 66 67 val mcontrolWireVec = tdata1Vec.map{ mod => { 68 val mcontrolWire = Wire(new Mcontrol) 69 mcontrolWire := mod.DATA.asUInt 70 mcontrolWire 71 }} 72 73 // More than one triggers can hit at the same time, but only fire one 74 // We select the first hit trigger to fire 75 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 76 val triggerFireAction = PriorityMux(triggerFireOH, tdata1Vec.map(_.getTriggerAction)).asUInt 77 val hasTriggerFire = hasExp && triggerCf.canFire 78 val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt) 79 val triggerCanFire = hasTriggerFire && (triggerFireAction === TrigAction.BreakpointExp.asUInt) && 80 Mux(privState.isModeM && !debugMode, tcontrol.MTE.asBool, true.B) // todo: Should trigger be fire in dmode? 81 82 // debug_exception_single 83 val hasSingleStep = hasExp && singleStep 84 85 val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 86 val hasDebugTrap = hasDebugException || hasDebugIntr 87 88 val tselect1H = UIntToOH(tselect.asUInt, TriggerNum).asBools 89 val chainVec = mcontrolWireVec.map(_.CHAIN.asBool) 90 val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b} 91 val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 92 93 val triggerUpdate = tdata1Update || tdata2Update 94 95 val mcontrolWdata = Wire(new Mcontrol) 96 mcontrolWdata := tdata1Wdata.DATA.asUInt 97 val tdata1TypeWdata = tdata1Wdata.TYPE 98 99 val mcontrolSelected = Wire(new Mcontrol) 100 mcontrolSelected := tdata1Selected.DATA.asUInt 101 102 val frontendTriggerUpdate = 103 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger || 104 mcontrolSelected.isFetchTrigger && triggerUpdate 105 106 val memTriggerUpdate = 107 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger || 108 mcontrolSelected.isMemAccTrigger && triggerUpdate 109 110 val triggerEnableVec = tdata1Vec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) => 111 tdata1.TYPE.isLegal && ( 112 mcontrol.M && privState.isModeM || 113 mcontrol.S && privState.isModeHS || 114 mcontrol.U && privState.isModeHU) 115 } 116 117 val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 118 case (tEnable, mod) => tEnable && mod.isFetchTrigger 119 } 120 val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 121 case (tEnable, mod) => tEnable && mod.isMemAccTrigger 122 } 123 124 io.out.frontendTrigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 125 io.out.frontendTrigger.tUpdate.bits.addr := tselect.asUInt 126 io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 127 io.out.frontendTrigger.tEnableVec := fetchTriggerEnableVec 128 io.out.memTrigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 129 io.out.memTrigger.tUpdate.bits.addr := tselect.asUInt 130 io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 131 io.out.memTrigger.tEnableVec := memAccTriggerEnableVec 132 133 io.out.triggerFrontendChange := frontendTriggerUpdate 134 io.out.newTriggerChainIsLegal := newTriggerChainIsLegal 135 136 io.out.hasDebugTrap := hasDebugTrap 137 io.out.hasDebugIntr := hasDebugIntr 138 io.out.triggerCanFire := triggerCanFire 139 io.out.hasSingleStep := hasSingleStep 140 io.out.hasTriggerFire := hasTriggerFire 141 io.out.hasDebugEbreakException := hasDebugEbreakException 142 io.out.breakPoint := breakPoint 143} 144 145class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { 146 val in = Input(new Bundle { 147 val trapInfo = ValidIO(new Bundle { 148 val trapVec = UInt(64.W) 149 val intrVec = UInt(64.W) 150 val isInterrupt = Bool() 151 val singleStep = Bool() 152 val triggerCf = new TriggerCf 153 }) 154 155 val privState = new PrivState 156 val debugMode = Bool() 157 158 val dcsr = new DcsrBundle 159 val tcontrol = new TcontrolBundle 160 val tselect = new TselectBundle(TriggerNum) 161 val tdata1Selected = new Tdata1Bundle 162 val tdata2Selected = new Tdata2Bundle 163 val tdata1Vec = Vec(TriggerNum, new Tdata1Bundle) 164 165 val tdata1Update = Bool() 166 val tdata2Update = Bool() 167 val tdata1Wdata = new Tdata1Bundle 168 }) 169 170 val out = Output(new Bundle{ 171 // trigger 172 val triggerFrontendChange = Bool() 173 val newTriggerChainIsLegal = Bool() 174 val memTrigger = new MemTdataDistributeIO() 175 val frontendTrigger = new FrontendTdataDistributeIO() 176 177 val hasDebugTrap = Bool() 178 val hasDebugIntr = Bool() 179 val hasSingleStep = Bool() 180 val hasTriggerFire = Bool() 181 val triggerCanFire = Bool() 182 val hasDebugEbreakException = Bool() 183 val breakPoint = Bool() 184 }) 185}