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