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