1package xiangshan.backend.fu.NewCSR 2 3import freechips.rocketchip.devices.debug.DebugModuleKey 4import org.chipsalliance.cde.config.Parameters 5import freechips.rocketchip.rocket.CSRs 6import chisel3._ 7import chisel3.util._ 8import utils.ConsecutiveOnes 9import xiangshan.backend.fu.NewCSR.CSRDefines._ 10import xiangshan.backend.fu.NewCSR.CSRDefines.{ 11 CSRWARLField => WARL, 12 CSRRWField => RW, 13 CSRROField => RO, 14} 15import xiangshan.backend.fu.NewCSR.CSRFunc._ 16import xiangshan.backend.fu.NewCSR.CSREvents._ 17import xiangshan.backend.fu.NewCSR.CSRBundles._ 18import CSRConfig._ 19import utility.SignExt 20import xiangshan.TriggerAction 21 22import scala.collection.immutable.SeqMap 23 24 25trait DebugLevel { self: NewCSR => 26 val tselect = Module(new CSRModule("Tselect", new TselectBundle(TriggerNum)) { 27 when (this.w.wen && this.w.wdata < TriggerNum.U) { 28 reg := this.w.wdata 29 }.otherwise { 30 reg := reg 31 } 32 }) 33 .setAddr(CSRs.tselect) 34 35 val tdata1 = Module(new CSRModule("Tdata1") with HasTdataSink { 36 regOut := tdataRead.tdata1 37 }) 38 .setAddr(CSRs.tdata1) 39 40 val tdata2 = Module(new CSRModule("Tdata2") with HasTdataSink { 41 regOut := tdataRead.tdata2 42 }) 43 .setAddr(CSRs.tdata2) 44 45 val tdata1RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i => 46 Module(new CSRModule(s"Trigger$i" + s"_Tdata1", new Tdata1Bundle) with HasdebugModeBundle { 47 when(wen){ 48 reg := wdata.writeTdata1(debugMode, chainable).asUInt 49 } 50 }) 51 ) 52 val tdata2RegVec: Seq[CSRModule[_]] = Range(0, TriggerNum).map(i => 53 Module(new CSRModule(s"Trigger$i" + s"_Tdata2", new Tdata2Bundle)) 54 ) 55 56 val tinfo = Module(new CSRModule("Tinfo", new TinfoBundle)) 57 .setAddr(CSRs.tinfo) 58 59 val tcontrol = Module(new CSRModule("Tcontrol", new TcontrolBundle) with TrapEntryMEventSinkBundle with MretEventSinkBundle) 60 .setAddr(CSRs.tcontrol) 61 62 val dcsr = Module(new CSRModule("Dcsr", new DcsrBundle) with TrapEntryDEventSinkBundle with DretEventSinkBundle) 63 .setAddr(CSRs.dcsr) 64 65 val dpc = Module(new CSRModule("Dpc", new Epc) with TrapEntryDEventSinkBundle) 66 .setAddr(CSRs.dpc) 67 68 val dscratch0 = Module(new CSRModule("Dscratch0", new DscratchBundle)) 69 .setAddr(CSRs.dscratch0) 70 71 val dscratch1 = Module(new CSRModule("Dscratch1", new DscratchBundle)) 72 .setAddr(CSRs.dscratch1) 73 74 val debugCSRMods = Seq( 75 tdata1, 76 tdata2, 77 tselect, 78 tinfo, 79 tcontrol, 80 dcsr, 81 dpc, 82 dscratch0, 83 dscratch1, 84 ) 85 86 val debugCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_ <: CSRBundle], UInt)] = SeqMap.from( 87 debugCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata)).iterator 88 ) 89 90 val debugCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 91 debugCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator 92 ) 93 94 private val tdata1Rdata = Mux1H( 95 tdata1RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata} 96 ) 97 98 private val tdata2Rdata = Mux1H( 99 tdata2RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata} 100 ) 101 102 debugCSRMods.foreach { mod => 103 mod match { 104 case m: HasTdataSink => 105 m.tdataRead.tdata1 := tdata1Rdata 106 m.tdataRead.tdata2 := tdata2Rdata 107 case _ => 108 } 109 } 110 111} 112 113// tselect 114class TselectBundle(triggerNum: Int) extends CSRBundle{ 115 override val len: Int = log2Up(triggerNum) 116 val ALL = WARL(len - 1, 0, wNoEffectWhen(WriteTselect)).withReset(0.U) 117 def WriteTselect(wdata: UInt) = { 118 wdata >= triggerNum.U 119 } 120} 121 122// tdata1 123class Tdata1Bundle extends CSRBundle{ 124 val TYPE = Tdata1Type(63, 60, wNoFilter).withReset(Tdata1Type.Disabled) 125 val DMODE = RW(59).withReset(0.U) 126 val DATA = RW(58, 0).withReset(0.U) 127 128 def getTriggerAction: CSREnumType = { 129 val res = Wire(new Mcontrol6) 130 res := this.asUInt 131 res.ACTION 132 } 133 134 def writeTdata1(debugMode: Bool, chainable: Bool): Tdata1Bundle = { 135 val res = Wire(new Tdata1Bundle) 136 res := this.asUInt 137 val dmode = this.DMODE.asBool && debugMode 138 res.TYPE := this.TYPE.legalize.asUInt 139 res.DMODE := dmode 140 when(this.TYPE.isLegal) { 141 val mcontrol6Res = Wire(new Mcontrol6) 142 mcontrol6Res := this.DATA.asUInt 143 res.DATA := mcontrol6Res.writeData(dmode, chainable).asUInt 144 }.otherwise{ 145 res.DATA := 0.U 146 } 147 res 148 } 149} 150 151class Mcontrol6 extends CSRBundle{ 152 override val len: Int = 59 153 // xiangshan don't support match = NAPOT 154 val UNCERTAIN = RO(26).withReset(0.U) 155 val HIT1 = RO(25).withReset(0.U) 156 val VS = RW(24).withReset(0.U) 157 val VU = RW(23).withReset(0.U) 158 val HIT0 = RO(22).withReset(0.U) 159 val SELECT = RW(21).withReset(0.U) 160 val SIZE = RW(18, 16).withReset(0.U) 161 val ACTION = TrigAction(15, 12, wNoFilter).withReset(TrigAction.BreakpointExp) 162 val CHAIN = RW(11).withReset(0.U) 163 val MATCH = TrigMatch(10, 7, wNoFilter).withReset(TrigMatch.EQ) 164 val M = RW(6).withReset(0.U) 165 val UNCERTAINEN = RO(5).withReset(0.U) 166 val S = RW(4).withReset(0.U) 167 val U = RW(3).withReset(0.U) 168 val EXECUTE = RW(2).withReset(0.U) 169 val STORE = RW(1).withReset(0.U) 170 val LOAD = RW(0).withReset(0.U) 171 172 def writeData(dmode: Bool, chainable: Bool): Mcontrol6 = { 173 val res = Wire(new Mcontrol6) 174 res := this.asUInt 175 res.SIZE := 0.U 176 res.SELECT := this.EXECUTE.asBool && this.SELECT.asBool 177 res.ACTION := this.ACTION.legalize(dmode).asUInt 178 res.CHAIN := this.CHAIN.asBool && chainable 179 res.MATCH := this.MATCH.legalize.asUInt 180 res 181 } 182 def isFetchTrigger: Bool = this.EXECUTE.asBool 183 def isMemAccTrigger: Bool = this.STORE || this.LOAD 184} 185 186 187object Tdata1Type extends CSREnum with WARLApply { 188 val None = Value(0.U) 189 val Legacy = Value(1.U) 190 val Mcontrol = Value(2.U) 191 val Icount = Value(3.U) 192 val Itrigger = Value(4.U) 193 val Etrigger = Value(5.U) 194 val Mcontrol6 = Value(6.U) 195 val Tmexttrigger = Value(7.U) 196 val Disabled = Value(15.U) 197 198 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(Mcontrol6) 199 200 override def legalize(enumeration: CSREnumType): CSREnumType = { 201 val res = WireInit(enumeration) 202 when(!enumeration.isLegal){ 203 res := Disabled.asUInt 204 } 205 res 206 } 207} 208 209object TrigAction extends CSREnum with WARLApply { 210 val BreakpointExp = Value(0.U) // raise breakpoint exception 211 val DebugMode = Value(1.U) // enter debug mode 212 val TraceOn = Value(2.U) 213 val TraceOff = Value(3.U) 214 val TraceNotify = Value(4.U) 215 216 override def isLegal(enumeration: CSREnumType, dmode: Bool): Bool = enumeration.isOneOf(BreakpointExp) || enumeration.isOneOf(DebugMode) && dmode 217 218 override def legalize(enumeration: CSREnumType, dmode: Bool): CSREnumType = { 219 val res = WireInit(enumeration) 220 when(!enumeration.isLegal(dmode)){ 221 res := BreakpointExp 222 } 223 res.asInstanceOf[CSREnumType] 224 } 225} 226 227object TrigMatch extends CSREnum with WARLApply { 228 val EQ = Value(0.U) 229 val NAPOT = Value(1.U) 230 val GE = Value(2.U) 231 val LT = Value(3.U) 232 val MASK_LO = Value(4.U) 233 val MASK_HI = Value(5.U) 234 val NE = Value(8.U) // not eq 235 val NNAPOT = Value(9.U) // not napot 236 val NMASK_LO = Value(12.U) // not mask low 237 val NMASK_HI = Value(13.U) // not mask high 238 def isRVSpecLegal(enumeration: CSREnumType) : Bool = enumeration.isOneOf( 239 EQ, NAPOT, GE, LT, MASK_LO, MASK_HI, 240 NE, NNAPOT, NMASK_LO, NMASK_HI, 241 ) 242 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(EQ, GE, LT) 243 244 override def legalize(enumeration: CSREnumType): CSREnumType = { 245 val res = WireInit(enumeration) 246 when(!enumeration.isLegal){ 247 res := EQ 248 } 249 res.asInstanceOf[CSREnumType] 250 } 251} 252 253 254// tdata2 255class Tdata2Bundle extends OneFieldBundle 256 257// Tinfo 258class TinfoBundle extends CSRBundle{ 259 // Version isn't in version 0.13 260 val VERSION = RO(31, 24).withReset(0.U) 261 // only support mcontrol6 262 val MCONTROL6EN = RO(6).withReset(1.U) 263} 264 265class TcontrolBundle extends CSRBundle{ 266 // M-mode previous trigger enable field 267 val MPTE = RW(7).withReset(0.U) 268 // M-mode trigger enable field 269 val MTE = RW(3).withReset(0.U) 270} 271 272// Dscratch 273class DscratchBundle extends OneFieldBundle 274 275 276class DcsrBundle extends CSRBundle { 277 override val len: Int = 32 278 val DEBUGVER = DcsrDebugVer(31, 28).withReset(DcsrDebugVer.Spec) // Debug implementation as it described in 0.13 draft // todo 279 // All ebreak Privileges are RW, instead of WARL, since XiangShan support U/S/VU/VS. 280 val EBREAKVS = RW( 17).withReset(0.U) 281 val EBREAKVU = RW( 16).withReset(0.U) 282 val EBREAKM = RW( 15).withReset(0.U) 283 val EBREAKS = RW( 13).withReset(0.U) 284 val EBREAKU = RW( 12).withReset(0.U) 285 // STEPIE is RW, instead of WARL, since XiangShan support interrupts being enabled single stepping. 286 val STEPIE = RW( 11).withReset(0.U) 287 val STOPCOUNT = RO( 10).withReset(0.U) // Stop count updating has not been supported 288 val STOPTIME = RO( 9).withReset(0.U) // Stop time updating has not been supported 289 val CAUSE = DcsrCause( 8, 6).withReset(DcsrCause.None) 290 val V = VirtMode( 5).withReset(VirtMode.Off) 291 // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode 292 // Whether use mstatus.mprv 293 val MPRVEN = RW( 4).withReset(0.U) 294 // TODO: support non-maskable interrupt 295 val NMIP = RO( 3).withReset(0.U) 296 // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode 297 val STEP = RW( 2).withReset(0.U) 298 val PRV = PrivMode( 1, 0).withReset(PrivMode.M) 299} 300 301object DcsrDebugVer extends CSREnum with ROApply { 302 val None = Value(0.U) 303 val Spec = Value(4.U) 304 val Custom = Value(15.U) 305} 306 307object DcsrCause extends CSREnum with ROApply { 308 val None = Value(0.U) 309 val Ebreak = Value(1.U) 310 val Trigger = Value(2.U) 311 val Haltreq = Value(3.U) 312 val Step = Value(4.U) 313 val Resethaltreq = Value(5.U) 314 val Group = Value(6.U) 315} 316 317trait HasTdataSink { self: CSRModule[_] => 318 val tdataRead = IO(Input(new Bundle { 319 val tdata1 = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width 320 val tdata2 = UInt(XLEN.W) 321 })) 322} 323trait HasdebugModeBundle { self: CSRModule[_] => 324 val debugMode = IO(Input(Bool())) 325 val chainable = IO(Input(Bool())) 326} 327 328/** 329 * debug Module MMIO Addr 330 */ 331trait DebugMMIO { 332 implicit val p: Parameters 333 334 def debugMMIO = p(DebugModuleKey).get 335 336 def BASE = debugMMIO.baseAddress 337 def DebugEntry = BASE + 0x800 338 def DebugException = BASE + 0x808 339 def HALTED = BASE + 0x100 340 def GOING = BASE + 0x104 341 def RESUMING = BASE + 0x108 342 def EXCEPTION = BASE + 0x10C 343 def WHERETO = BASE + 0x300 344 def DATA = BASE + 0x380 345 def IMPEBREAK = DATA - 0x4 346 def PROGBUF = DATA - 4 * debugMMIO.nProgramBufferWords 347 def ABSTRACT = PROGBUF - 4 * (if(debugMMIO.atzero) 2 else 5) 348 def FLAGS = BASE + 0x400 349} 350 351object TriggerUtil { 352 /** 353 * Check if chain vector is legal 354 * @param chainVec 355 * @param chainLen 356 * @return true.B if the max length of chain don't exceed the permitted length 357 */ 358 def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = { 359 !ConsecutiveOnes(chainVec, chainLen) 360 } 361 362 /** 363 * Generate Trigger action 364 * @return triggerAction return 365 * @param triggerCanFireVec 366 * @param actionVec tdata.action 367 * @param triggerCanRaiseBpExp from csr 368 */ 369 def triggerActionGen(triggerAction: UInt, triggerCanFireVec: Vec[Bool], actionVec: Vec[UInt], triggerCanRaiseBpExp: Bool): Unit = { 370 // More than one triggers can hit at the same time, but only fire one. 371 // We select the first hit trigger to fire. 372 val hasTriggerFire = triggerCanFireVec.asUInt.orR 373 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 374 val triggerFireAction = PriorityMux(triggerFireOH, actionVec).asUInt 375 val actionIsBPExp = hasTriggerFire && (triggerFireAction === TrigAction.BreakpointExp.asUInt) 376 val actionIsDmode = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt) 377 val breakPointExp = actionIsBPExp && triggerCanRaiseBpExp 378 379 // todo: add more for trace 380 triggerAction := MuxCase(TriggerAction.None, Seq( 381 breakPointExp -> TriggerAction.BreakpointExp, 382 actionIsDmode -> TriggerAction.DebugMode, 383 )) 384 } 385}