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 rdata := tdataRead.tdata1 28 regOut := 0.U 29 }) 30 .setAddr(CSRs.tdata1) 31 32 val tdata2 = Module(new CSRModule("Tdata2") with HasTdataSink { 33 rdata := tdataRead.tdata2 34 regOut := 0.U 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 Dpc) 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(tselectWidth - 1, 0, wNoEffectWhen(WriteTselect)) // todo: paramterize 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) 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(enum: CSREnumType): Bool = enum.isOneOf(Mcontrol) 194 195 override def legalize(enum: CSREnumType): CSREnumType = { 196 val res = WireInit(enum) 197 when(!enum.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(enum: CSREnumType, dmode: Bool): Bool = enum.isOneOf(BreakpointExp) || enum.isOneOf(DebugMode) && dmode 212 213 override def legalize(enum: CSREnumType, dmode: Bool): CSREnumType = { 214 val res = WireInit(enum) 215 when(!enum.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(enum: CSREnumType) : Bool = enum.isOneOf( 234 EQ, NAPOT, GE, LT, MASK_LO, MASK_HI, 235 NE, NNAPOT, NMASK_LO, NMASK_HI, 236 ) 237 override def isLegal(enum: CSREnumType): Bool = enum.isOneOf(EQ, GE, LT) 238 239 override def legalize(enum: CSREnumType): CSREnumType = { 240 val res = WireInit(enum) 241 when(!enum.isLegal){ 242 res := EQ 243 } 244 res.asInstanceOf[CSREnumType] 245 } 246} 247 248 249// tdata2 250class Tdata2Bundle extends CSRBundle{ 251 val ALL = RW(63, 0) 252} 253 254// Tinfo 255class TinfoBundle extends CSRBundle{ 256 // Version isn't in version 0.13 257 val VERSION = RO(31, 24).withReset(0.U) 258 // only support mcontrol 259 val MCONTROLEN = RO(2).withReset(1.U) 260} 261 262class TcontrolBundle extends CSRBundle{ 263 // M-mode previous trigger enable field 264 val MPTE = RW(7).withReset(0.U) 265 // M-mode trigger enable field 266 val MTE = RW(3).withReset(0.U) 267} 268 269// Dscratch 270class DscratchBundle extends CSRBundle{ 271 val ALL = RW(63, 0) 272} 273 274 275class DcsrBundle extends CSRBundle { 276 override val len: Int = 32 277 val DEBUGVER = DcsrDebugVer(31, 28).withReset(DcsrDebugVer.Spec) // Debug implementation as it described in 0.13 draft // todo 278 // All ebreak Privileges are RW, instead of WARL, since XiangShan support U/S/VU/VS. 279 val EBREAKVS = RW( 17).withReset(0.U) 280 val EBREAKVU = RW( 16).withReset(0.U) 281 val EBREAKM = RW( 15).withReset(0.U) 282 val EBREAKS = RW( 13).withReset(0.U) 283 val EBREAKU = RW( 12).withReset(0.U) 284 // STEPIE is RW, instead of WARL, since XiangShan support interrupts being enabled single stepping. 285 val STEPIE = RW( 11).withReset(0.U) 286 val STOPCOUNT = RO( 10).withReset(0.U) // Stop count updating has not been supported 287 val STOPTIME = RO( 9).withReset(0.U) // Stop time updating has not been supported 288 val CAUSE = DcsrCause( 8, 6).withReset(DcsrCause.None) 289 val V = VirtMode( 5).withReset(VirtMode.Off) 290 // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode 291 // Whether use mstatus.mprv 292 val MPRVEN = RW( 4).withReset(0.U) 293 // TODO: support non-maskable interrupt 294 val NMIP = RO( 3).withReset(0.U) 295 // MPRVEN is RW, instead of WARL, since XiangShan support use mstatus.mprv in debug mode 296 val STEP = RW( 2).withReset(0.U) 297 val PRV = PrivMode( 1, 0).withReset(PrivMode.M) 298} 299 300class Dpc extends CSRBundle { 301 val ALL = RW(63, 1) 302} 303 304 305object DcsrDebugVer extends CSREnum with ROApply { 306 val None = Value(0.U) 307 val Spec = Value(4.U) 308 val Custom = Value(15.U) 309} 310 311object DcsrCause extends CSREnum with ROApply { 312 val None = Value(0.U) 313 val Ebreak = Value(1.U) 314 val Trigger = Value(2.U) 315 val Haltreq = Value(3.U) 316 val Step = Value(4.U) 317 val Resethaltreq = Value(5.U) 318 val Group = Value(6.U) 319} 320 321trait HasTdataSink { self: CSRModule[_] => 322 val tdataRead = IO(Input(new Bundle { 323 val tdata1 = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width 324 val tdata2 = UInt(XLEN.W) 325 })) 326} 327trait HasdebugModeBundle { self: CSRModule[_] => 328 val debugMode = IO(Input(Bool())) 329 val chainable = IO(Input(Bool())) 330} 331 332/** 333 * debug Module MMIO Addr 334 */ 335trait DebugMMIO { 336 implicit val p: Parameters 337 338 def debugMMIO = p(DebugModuleKey).get 339 340 def BASE = debugMMIO.baseAddress 341 def DebugEntry = BASE + 0x800 342 def DebugException = BASE + 0x808 343 def HALTED = BASE + 0x100 344 def GOING = BASE + 0x104 345 def RESUMING = BASE + 0x108 346 def EXCEPTION = BASE + 0x10C 347 def WHERETO = BASE + 0x300 348 def DATA = BASE + 0x380 349 def IMPEBREAK = DATA - 0x4 350 def PROGBUF = DATA - 4 * debugMMIO.nProgramBufferWords 351 def ABSTRACT = PROGBUF - 4 * (if(debugMMIO.atzero) 2 else 5) 352 def FLAGS = BASE + 0x400 353} 354 355object TriggerUtil { 356 /** 357 * Check if chain vector is legal 358 * @param chainVec 359 * @param chainLen 360 * @return true.B if the max length of chain don't exceed the permitted length 361 */ 362 def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = { 363 !ConsecutiveOnes(chainVec, chainLen) 364 } 365}