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