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.backend.fu.util.SdtrigExt 10import xiangshan._ 11 12class Debug(implicit val p: Parameters) extends Module with HasXSParameter { 13 val io = IO(new DebugIO) 14 15 private val trapInfo = io.in.trapInfo 16 private val hasTrap = trapInfo.valid 17 private val trapIsInterrupt = trapInfo.bits.isInterrupt 18 private val intrVec = trapInfo.bits.intrVec 19 private val trapVec = trapInfo.bits.trapVec 20 private val singleStep = trapInfo.bits.singleStep 21 private val triggerCf = io.in.trapInfo.bits.triggerCf 22 23 private val privState = io.in.privState 24 private val debugMode = io.in.debugMode 25 26 private val dcsr = io.in.dcsr 27 private val tcontrol = io.in.tcontrol 28 private val tselect = io.in.tselect 29 private val tdata1Selected = io.in.tdata1Selected 30 private val tdata2Selected = io.in.tdata2Selected 31 private val tdata1Vec = io.in.tdata1Vec 32 33 private val tdata1Update = io.in.tdata1Update 34 private val tdata2Update = io.in.tdata2Update 35 private val tdata1Wdata = io.in.tdata1Wdata 36 37 /** 38 * ways to entry Dmode: 39 * 1. debug intr(from external debug module) 40 * 2. ebreak inst in nonDmode 41 * 3. trigger fire in nonDmode 42 * 4. single step(debug module set dcsr.step before hart resume) 43 */ 44 // debug_intr 45 val hasIntr = hasTrap && trapIsInterrupt 46 val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG) 47 48 // debug_exception_ebreak 49 val hasExp = hasTrap && !trapIsInterrupt 50 val breakPoint = trapVec(ExceptionNO.breakPoint).asBool 51 val hasBreakPoint = hasExp && breakPoint 52 val ebreakEnterDebugMode = 53 (privState.isModeM && dcsr.EBREAKM.asBool) || 54 (privState.isModeHS && dcsr.EBREAKS.asBool) || 55 (privState.isModeHU && dcsr.EBREAKU.asBool) || 56 (privState.isModeVS && dcsr.EBREAKVS.asBool) || 57 (privState.isModeVU && dcsr.EBREAKVU.asBool) 58 val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 59 60 // debug_exception_trigger 61 val triggerFrontendHitVec = triggerCf.frontendHit 62 val triggerMemHitVec = triggerCf.backendHit 63 val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit 64 val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt 65 val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt 66 val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec 67 68 val mcontrolWireVec = tdata1Vec.map{ mod => { 69 val mcontrolWire = Wire(new Mcontrol) 70 mcontrolWire := mod.DATA.asUInt 71 mcontrolWire 72 }} 73 74 // More than one triggers can hit at the same time, but only fire one 75 // We select the first hit trigger to fire 76 val triggerCanRaiseBpExp = Mux(privState.isModeM && !debugMode, tcontrol.MTE.asBool, true.B) 77 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 78 val triggerFireAction = PriorityMux(triggerFireOH, tdata1Vec.map(_.getTriggerAction)).asUInt 79 val hasTriggerFire = hasExp && triggerCf.canFire 80 val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt) 81 val triggerCanFire = hasTriggerFire && (triggerFireAction === TrigAction.BreakpointExp.asUInt) && triggerCanRaiseBpExp // todo: Should trigger be fire in dmode? 82 83 // debug_exception_single 84 val hasSingleStep = hasExp && singleStep 85 86 val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 87 val hasDebugTrap = hasDebugException || hasDebugIntr 88 89 val tselect1H = UIntToOH(tselect.asUInt, TriggerNum).asBools 90 val chainVec = mcontrolWireVec.map(_.CHAIN.asBool) 91 val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b} 92 val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 93 94 val triggerUpdate = tdata1Update || tdata2Update 95 96 val mcontrolWdata = Wire(new Mcontrol) 97 mcontrolWdata := tdata1Wdata.DATA.asUInt 98 val tdata1TypeWdata = tdata1Wdata.TYPE 99 100 val mcontrolSelected = Wire(new Mcontrol) 101 mcontrolSelected := tdata1Selected.DATA.asUInt 102 103 val frontendTriggerUpdate = 104 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger || 105 mcontrolSelected.isFetchTrigger && triggerUpdate 106 107 val memTriggerUpdate = 108 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger || 109 mcontrolSelected.isMemAccTrigger && triggerUpdate 110 111 val triggerEnableVec = tdata1Vec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) => 112 tdata1.TYPE.isLegal && ( 113 mcontrol.M && privState.isModeM || 114 mcontrol.S && privState.isModeHS || 115 mcontrol.U && privState.isModeHU) 116 } 117 118 val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 119 case (tEnable, mod) => tEnable && mod.isFetchTrigger 120 } 121 val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 122 case (tEnable, mod) => tEnable && mod.isMemAccTrigger 123 } 124 125 io.out.frontendTrigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 126 io.out.frontendTrigger.tUpdate.bits.addr := tselect.asUInt 127 io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 128 io.out.frontendTrigger.tEnableVec := fetchTriggerEnableVec 129 130 io.out.memTrigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 131 io.out.memTrigger.tUpdate.bits.addr := tselect.asUInt 132 io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 133 io.out.memTrigger.tEnableVec := memAccTriggerEnableVec 134 io.out.memTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 135 136 io.out.triggerFrontendChange := frontendTriggerUpdate 137 io.out.newTriggerChainIsLegal := newTriggerChainIsLegal 138 139 io.out.hasDebugTrap := hasDebugTrap 140 io.out.hasDebugIntr := hasDebugIntr 141 io.out.triggerCanFire := triggerCanFire 142 io.out.hasSingleStep := hasSingleStep 143 io.out.hasTriggerFire := hasTriggerFire 144 io.out.hasDebugEbreakException := hasDebugEbreakException 145 io.out.breakPoint := breakPoint 146} 147 148class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { 149 val in = Input(new Bundle { 150 val trapInfo = ValidIO(new Bundle { 151 val trapVec = UInt(64.W) 152 val intrVec = UInt(64.W) 153 val isInterrupt = Bool() 154 val singleStep = Bool() 155 val triggerCf = new TriggerCf 156 }) 157 158 val privState = new PrivState 159 val debugMode = Bool() 160 161 val dcsr = new DcsrBundle 162 val tcontrol = new TcontrolBundle 163 val tselect = new TselectBundle(TriggerNum) 164 val tdata1Selected = new Tdata1Bundle 165 val tdata2Selected = new Tdata2Bundle 166 val tdata1Vec = Vec(TriggerNum, new Tdata1Bundle) 167 168 val tdata1Update = Bool() 169 val tdata2Update = Bool() 170 val tdata1Wdata = new Tdata1Bundle 171 }) 172 173 val out = Output(new Bundle{ 174 // trigger 175 val triggerFrontendChange = Bool() 176 val newTriggerChainIsLegal = Bool() 177 val memTrigger = new MemTdataDistributeIO() 178 val frontendTrigger = new FrontendTdataDistributeIO() 179 180 val hasDebugTrap = Bool() 181 val hasDebugIntr = Bool() 182 val hasSingleStep = Bool() 183 val hasTriggerFire = Bool() 184 val triggerCanFire = Bool() 185 val hasDebugEbreakException = Bool() 186 val breakPoint = Bool() 187 }) 188} 189 190class CsrTriggerBundle(implicit val p: Parameters) extends Bundle with HasXSParameter { 191 val tdataVec = Vec(TriggerNum, new MatchTriggerIO) 192 val tEnableVec = Vec(TriggerNum, Bool()) 193 val triggerCanRaiseBpExp = Bool() 194} 195class StoreTrigger(implicit val p: Parameters)extends Module with HasXSParameter with SdtrigExt { 196 val io = IO(new Bundle(){ 197 val fromCsrTrigger = Input(new CsrTriggerBundle) 198 199 val fromStore = Input(new Bundle { 200 val vaddr = UInt(VAddrBits.W) 201 }) 202 203 val toStore = Output(new Bundle{ 204 val triggerHitVec = Vec(TriggerNum, Bool()) 205 val triggerCanFireVec = Vec(TriggerNum, Bool()) 206 val breakPointExp = Bool() 207 }) 208 }) 209 val tdataVec = io.fromCsrTrigger.tdataVec 210 val tEnableVec = io.fromCsrTrigger.tEnableVec 211 val triggerCanRaiseBpExp = io.fromCsrTrigger.triggerCanRaiseBpExp 212 val vaddr = io.fromStore.vaddr 213 214 val triggerTimingVec = VecInit(tdataVec.map(_.timing)) 215 val triggerChainVec = VecInit(tdataVec.map(_.chain)) 216 217 val triggerHitVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B))) 218 val triggerCanFireVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B))) 219 220 for (i <- 0 until TriggerNum) { 221 triggerHitVec(i) := !tdataVec(i).select && TriggerCmp( 222 vaddr, 223 tdataVec(i).tdata2, 224 tdataVec(i).matchType, 225 tEnableVec(i) && tdataVec(i).store 226 ) 227 } 228 TriggerCheckCanFire(TriggerNum, triggerCanFireVec, triggerHitVec, triggerTimingVec, triggerChainVec) 229 230 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 231 val triggerFireAction = PriorityMux(triggerFireOH, tdataVec.map(_.action)).asUInt 232 val breakPointExp = ((triggerFireAction === TrigAction.BreakpointExp.asUInt) && triggerCanRaiseBpExp || 233 (triggerFireAction === TrigAction.DebugMode.asUInt)) && triggerCanFireVec.asUInt.orR 234 235 io.toStore.triggerHitVec := triggerHitVec 236 io.toStore.triggerCanFireVec := triggerCanFireVec 237 io.toStore.breakPointExp := breakPointExp 238}