1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState 7import xiangshan.backend.fu.util.CSRConst 8import xiangshan.backend.fu.util.SdtrigExt 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 isDebugIntr = trapInfo.bits.isDebugIntr 18 private val trapVec = trapInfo.bits.trapVec 19 private val singleStep = trapInfo.bits.singleStep 20 private val trigger = io.in.trapInfo.bits.trigger 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 tselect = io.in.tselect 27 private val tdata1Selected = io.in.tdata1Selected 28 private val tdata2Selected = io.in.tdata2Selected 29 private val tdata1Vec = io.in.tdata1Vec 30 31 private val tdata1Update = io.in.tdata1Update 32 private val tdata2Update = io.in.tdata2Update 33 private val tdata1Wdata = io.in.tdata1Wdata 34 35 /** 36 * ways to entry Dmode: 37 * 1. debug intr(from external debug module) 38 * 2. ebreak inst in nonDmode 39 * 3. trigger fire in nonDmode 40 * 4. single step(debug module set dcsr.step before hart resume) 41 * 5. critical error state(when dcsr.cetrig assert) 42 */ 43 // debug_intr 44 val hasIntr = hasTrap && trapIsInterrupt 45 val hasDebugIntr = hasIntr && isDebugIntr 46 47 // debug_exception_ebreak 48 val hasExp = hasTrap && !trapIsInterrupt 49 val breakPoint = trapVec(ExceptionNO.breakPoint).asBool 50 val isEbreak = hasExp && breakPoint && !TriggerAction.isExp(trigger) 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 = isEbreak && ebreakEnterDebugMode 58 59 // debug_exception_trigger 60 val mcontrol6WireVec = tdata1Vec.map{ mod => { 61 val mcontrol6Wire = Wire(new Mcontrol6) 62 mcontrol6Wire := mod.DATA.asUInt 63 mcontrol6Wire 64 }} 65 66 val triggerCanRaiseBpExp = io.in.triggerCanRaiseBpExp 67 val triggerEnterDebugMode = hasExp && TriggerAction.isDmode(trigger) 68 69 // debug_exception_single 70 val hasSingleStep = hasExp && singleStep 71 72 73 // critical error state 74 val criticalErrorStateEnterDebug = trapInfo.bits.criticalErrorState && dcsr.CETRIG.asBool 75 76 val hasDebugException = hasDebugEbreakException || triggerEnterDebugMode || hasSingleStep || criticalErrorStateEnterDebug 77 val hasDebugTrap = hasDebugException || hasDebugIntr 78 79 val tselect1H = UIntToOH(tselect.asUInt, TriggerNum).asBools 80 val chainVec = mcontrol6WireVec.map(_.CHAIN.asBool) 81 val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b} 82 val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 83 84 val triggerUpdate = tdata1Update || tdata2Update 85 86 val mcontrol6Wdata = Wire(new Mcontrol6) 87 mcontrol6Wdata := tdata1Wdata.DATA.asUInt 88 val tdata1TypeWdata = tdata1Wdata.TYPE 89 90 val mcontrol6Selected = Wire(new Mcontrol6) 91 mcontrol6Selected := tdata1Selected.DATA.asUInt 92 93 val frontendTriggerUpdate = 94 tdata1Update && tdata1TypeWdata.isLegal && mcontrol6Wdata.isFetchTrigger || 95 mcontrol6Selected.isFetchTrigger && triggerUpdate 96 97 val memTriggerUpdate = 98 tdata1Update && tdata1TypeWdata.isLegal && mcontrol6Wdata.isMemAccTrigger || 99 mcontrol6Selected.isMemAccTrigger && triggerUpdate 100 101 val triggerEnableVec = tdata1Vec.zip(mcontrol6WireVec).map { case(tdata1, mcontrol6) => 102 tdata1.TYPE.isLegal && ( 103 mcontrol6.M && privState.isModeM || 104 mcontrol6.S && privState.isModeHS || 105 mcontrol6.U && privState.isModeHU || 106 mcontrol6.VS && privState.isModeVS || 107 mcontrol6.VU && privState.isModeVU) 108 } 109 110 val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrol6WireVec).map { 111 case (tEnable, mod) => tEnable && mod.isFetchTrigger 112 } 113 val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrol6WireVec).map { 114 case (tEnable, mod) => tEnable && mod.isMemAccTrigger 115 } 116 117 io.out.frontendTrigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 118 io.out.frontendTrigger.tUpdate.bits.addr := tselect.asUInt 119 io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 120 io.out.frontendTrigger.tEnableVec := fetchTriggerEnableVec 121 io.out.frontendTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 122 io.out.frontendTrigger.debugMode := debugMode 123 124 io.out.memTrigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 125 io.out.memTrigger.tUpdate.bits.addr := tselect.asUInt 126 io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 127 io.out.memTrigger.tEnableVec := memAccTriggerEnableVec 128 io.out.memTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 129 io.out.memTrigger.debugMode := debugMode 130 131 io.out.triggerFrontendChange := frontendTriggerUpdate 132 io.out.newTriggerChainIsLegal := newTriggerChainIsLegal 133 134 io.out.hasDebugTrap := hasDebugTrap 135 io.out.hasDebugIntr := hasDebugIntr 136 io.out.hasSingleStep := hasSingleStep 137 io.out.triggerEnterDebugMode := triggerEnterDebugMode 138 io.out.hasDebugEbreakException := hasDebugEbreakException 139 io.out.breakPoint := breakPoint 140 io.out.criticalErrorStateEnterDebug := criticalErrorStateEnterDebug 141} 142 143class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { 144 val in = Input(new Bundle { 145 val trapInfo = ValidIO(new Bundle { 146 val trapVec = UInt(64.W) 147 val isDebugIntr = Bool() 148 val isInterrupt = Bool() 149 val singleStep = Bool() 150 val trigger = TriggerAction() 151 val criticalErrorState = Bool() 152 }) 153 154 val privState = new PrivState 155 val debugMode = Bool() 156 157 val dcsr = new DcsrBundle 158 val tselect = new TselectBundle(TriggerNum) 159 val tdata1Selected = new Tdata1Bundle 160 val tdata2Selected = new Tdata2Bundle 161 val tdata1Vec = Vec(TriggerNum, new Tdata1Bundle) 162 val triggerCanRaiseBpExp = Bool() 163 164 val tdata1Update = Bool() 165 val tdata2Update = Bool() 166 val tdata1Wdata = new Tdata1Bundle 167 }) 168 169 val out = Output(new Bundle{ 170 // trigger 171 val triggerFrontendChange = Bool() 172 val newTriggerChainIsLegal = Bool() 173 val memTrigger = new MemTdataDistributeIO() 174 val frontendTrigger = new FrontendTdataDistributeIO() 175 176 val hasDebugTrap = Bool() 177 val hasDebugIntr = Bool() 178 val hasSingleStep = Bool() 179 val triggerEnterDebugMode = Bool() 180 val hasDebugEbreakException = Bool() 181 val breakPoint = Bool() 182 val criticalErrorStateEnterDebug = Bool() 183 }) 184} 185 186class CsrTriggerBundle(implicit val p: Parameters) extends Bundle with HasXSParameter { 187 val tdataVec = Vec(TriggerNum, new MatchTriggerIO) 188 val tEnableVec = Vec(TriggerNum, Bool()) 189 val debugMode = Bool() 190 val triggerCanRaiseBpExp = Bool() 191} 192 193object MemType { 194 val LOAD = true 195 val STORE = false 196} 197 198 199class BaseTriggerIO(implicit p: Parameters) extends XSBundle{ 200 val fromCsrTrigger = Input(new CsrTriggerBundle) 201 202 val fromLoadStore = Input(new Bundle { 203 val vaddr = UInt(VAddrBits.W) 204 val isVectorUnitStride = Bool() 205 val mask = UInt((VLEN/8).W) 206 }) 207 208 val toLoadStore = Output(new Bundle{ 209 val triggerAction = TriggerAction() 210 val triggerVaddr = UInt(VAddrBits.W) 211 val triggerMask = UInt((VLEN/8).W) 212 }) 213} 214 215 216abstract class BaseTrigger()(implicit val p: Parameters) extends Module with HasXSParameter with SdtrigExt { 217 lazy val io = IO(new BaseTriggerIO) 218 219 def getTriggerHitVec(): Vec[Bool] 220 def highBitsEq(): Vec[Bool] 221 222 val tdataVec = io.fromCsrTrigger.tdataVec 223 val tEnableVec = io.fromCsrTrigger.tEnableVec 224 val triggerCanRaiseBpExp = io.fromCsrTrigger.triggerCanRaiseBpExp 225 val debugMode = io.fromCsrTrigger.debugMode 226 val vaddr = io.fromLoadStore.vaddr 227 228 val triggerTimingVec = VecInit(tdataVec.map(_.timing)) 229 val triggerChainVec = VecInit(tdataVec.map(_.chain)) 230 231 // Trigger can't hit/fire in debug mode. 232 val triggerHitVec = getTriggerHitVec() 233 val triggerCanFireVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B))) 234 // for vector unit-stride, match Type only support equal 235 val lowBitWidth = log2Up(VLEN/8) 236 val isVectorStride = io.fromLoadStore.isVectorUnitStride 237 val mask = io.fromLoadStore.mask 238 239 val highEq = highBitsEq() 240 241 val lowMatch = tdataVec.map(tdata => UIntToOH(tdata.tdata2(lowBitWidth-1, 0)) & mask) 242 val lowEq = VecInit(lowMatch.map(lm => lm.orR)) 243 244 val hitVecVectorStride = VecInit(highEq.zip(lowEq).map{case(hi, lo) => hi && lo}) 245 246 TriggerCheckCanFire(TriggerNum, triggerCanFireVec, Mux(isVectorStride, hitVecVectorStride, triggerHitVec), triggerTimingVec, triggerChainVec) 247 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 248 val triggerVaddr = PriorityMux(triggerFireOH, VecInit(tdataVec.map(_.tdata2))).asUInt 249 val triggerMask = PriorityMux(triggerFireOH, VecInit(tdataVec.map(x => UIntToOH(x.tdata2(lowBitWidth-1, 0))))).asUInt 250 251 val actionVec = VecInit(tdataVec.map(_.action)) 252 val triggerAction = Wire(TriggerAction()) 253 TriggerUtil.triggerActionGen(triggerAction, triggerCanFireVec, actionVec, triggerCanRaiseBpExp) 254 255 io.toLoadStore.triggerAction := triggerAction 256 io.toLoadStore.triggerVaddr := triggerVaddr 257 io.toLoadStore.triggerMask := triggerMask 258} 259 260 261class MemTrigger(memType: Boolean = MemType.LOAD)(override implicit val p: Parameters) extends BaseTrigger { 262 263 override def getTriggerHitVec(): Vec[Bool] = { 264 val triggerHitVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B))) 265 for (i <- 0 until TriggerNum) { 266 triggerHitVec(i) := !tdataVec(i).select && !debugMode && TriggerCmp( 267 vaddr, 268 tdataVec(i).tdata2, 269 tdataVec(i).matchType, 270 tEnableVec(i) && (if(memType == MemType.LOAD) tdataVec(i).load else tdataVec(i).store) 271 ) 272 } 273 triggerHitVec 274 } 275 276 override def highBitsEq(): Vec[Bool] = { 277 VecInit(tdataVec.zip(tEnableVec).map{ case(tdata, en) => 278 !tdata.select && !debugMode && en && 279 (if(memType == MemType.LOAD) tdata.load else tdata.store) && 280 (vaddr >> lowBitWidth) === (tdata.tdata2 >> lowBitWidth) 281 }) 282 } 283} 284 285class VSegmentTrigger(override implicit val p: Parameters) extends BaseTrigger { 286 287 class VSegmentTriggerIO extends BaseTriggerIO{ 288 val memType = Input(Bool()) 289 } 290 291 override lazy val io = IO(new VSegmentTriggerIO) 292 293 override def getTriggerHitVec(): Vec[Bool] = { 294 val triggerHitVec = WireInit(VecInit(Seq.fill(TriggerNum)(false.B))) 295 for (i <- 0 until TriggerNum) { 296 triggerHitVec(i) := !tdataVec(i).select && !debugMode && TriggerCmp( 297 vaddr, 298 tdataVec(i).tdata2, 299 tdataVec(i).matchType, 300 tEnableVec(i) && Mux(io.memType === MemType.LOAD.asBool, tdataVec(i).load, tdataVec(i).store) 301 ) 302 } 303 triggerHitVec 304 } 305 306 override def highBitsEq(): Vec[Bool] = { 307 VecInit(tdataVec.zip(tEnableVec).map{ case(tdata, en) => 308 !tdata.select && !debugMode && en && 309 Mux(io.memType === MemType.LOAD.asBool, tdata.load, tdata.store) && 310 (vaddr >> lowBitWidth) === (tdata.tdata2 >> lowBitWidth) 311 }) 312 } 313}