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 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 60 }) 61 .setAddr(CSRs.dpc) 62 63 val dscratch0 = Module(new CSRModule("Dscratch0", new DscratchBundle)) 64 .setAddr(CSRs.dscratch0) 65 66 val dscratch1 = Module(new CSRModule("Dscratch1", new DscratchBundle)) 67 .setAddr(CSRs.dscratch1) 68 69 val debugCSRMods = Seq( 70 tdata1, 71 tdata2, 72 tselect, 73 tinfo, 74 tcontrol, 75 dcsr, 76 dpc, 77 dscratch0, 78 dscratch1, 79 ) 80 81 val debugCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_ <: CSRBundle], UInt)] = SeqMap.from( 82 debugCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata)).iterator 83 ) 84 85 val debugCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 86 debugCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator 87 ) 88 89 private val tdata1Rdata = Mux1H( 90 tdata1RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata} 91 ) 92 93 private val tdata2Rdata = Mux1H( 94 tdata2RegVec.zipWithIndex.map{case (mod, idx) => (tselect.rdata === idx.U) -> mod.rdata} 95 ) 96 97 debugCSRMods.foreach { mod => 98 mod match { 99 case m: HasTdataSink => 100 m.tdataRead.tdata1 := tdata1Rdata 101 m.tdataRead.tdata2 := tdata2Rdata 102 case _ => 103 } 104 } 105 106} 107 108// tselect 109class TselectBundle(triggerNum: Int) extends CSRBundle{ 110 override val len: Int = log2Up(triggerNum) 111 val ALL = WARL(len - 1, 0, wNoEffectWhen(WriteTselect)).withReset(0.U) 112 def WriteTselect(wdata: UInt) = { 113 wdata >= triggerNum.U 114 } 115} 116 117// tdata1 118class Tdata1Bundle extends CSRBundle{ 119 val TYPE = Tdata1Type(63, 60, wNoFilter).withReset(Tdata1Type.Disabled) 120 val DMODE = RW(59).withReset(0.U) 121 val DATA = RW(58, 0).withReset(0.U) 122 123 def getTriggerAction: CSREnumType = { 124 val res = Wire(new Mcontrol) 125 res := this.asUInt 126 res.ACTION 127 } 128 129 def writeTdata1(debugMode: Bool, chainable: Bool): Tdata1Bundle = { 130 val res = Wire(new Tdata1Bundle) 131 res := this.asUInt 132 val dmode = this.DMODE.asBool && debugMode 133 res.TYPE := this.TYPE.legalize.asUInt 134 res.DMODE := dmode 135 when(this.TYPE.isLegal) { 136 val mcontrolRes = Wire(new Mcontrol) 137 mcontrolRes := this.DATA.asUInt 138 res.DATA := mcontrolRes.writeData(dmode, chainable).asUInt 139 }.otherwise{ 140 res.DATA := 0.U 141 } 142 res 143 } 144} 145 146class Mcontrol extends CSRBundle{ 147 override val len: Int = 59 148 // xiangshan don't support match = NAPOT 149 val MASKMAX = RO(58, 53).withReset(0.U) 150 val SIZEHI = RW(22, 21).withReset(0.U) 151 val HIT = RW(20).withReset(0.U) 152 val SELECT = RW(19).withReset(0.U) 153 val TIMING = RW(18).withReset(0.U) 154 val SIZELO = RW(17, 16).withReset(0.U) 155 val ACTION = TrigAction(15, 12, wNoFilter).withReset(TrigAction.BreakpointExp) 156 val CHAIN = RW(11).withReset(0.U) 157 val MATCH = TrigMatch(10, 7, wNoFilter).withReset(TrigMatch.EQ) 158 val M = RW(6).withReset(0.U) 159 val S = RW(4).withReset(0.U) 160 val U = RW(3).withReset(0.U) 161 val EXECUTE = RW(2).withReset(0.U) 162 val STORE = RW(1).withReset(0.U) 163 val LOAD = RW(0).withReset(0.U) 164 165 def writeData(dmode: Bool, chainable: Bool): Mcontrol = { 166 val res = Wire(new Mcontrol) 167 res := this.asUInt 168 res.MASKMAX := 0.U 169 res.SIZEHI := 0.U 170 res.HIT := false.B 171 res.SELECT := this.EXECUTE.asBool && this.SELECT.asBool 172 res.TIMING := false.B 173 res.SIZELO := 0.U 174 res.ACTION := this.ACTION.legalize(dmode).asUInt 175 res.CHAIN := this.CHAIN.asBool && chainable 176 res.MATCH := this.MATCH.legalize.asUInt 177 res 178 } 179 def isFetchTrigger: Bool = this.EXECUTE.asBool 180 def isMemAccTrigger: Bool = this.STORE || this.LOAD 181} 182 183 184object Tdata1Type extends CSREnum with WARLApply { 185 val None = Value(0.U) 186 val Legacy = Value(1.U) 187 val Mcontrol = Value(2.U) 188 val Icount = Value(3.U) 189 val Itrigger = Value(4.U) 190 val Etrigger = Value(5.U) 191 val Mcontrol6 = Value(6.U) 192 val Tmexttrigger = Value(7.U) 193 val Disabled = Value(15.U) 194 195 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(Mcontrol) 196 197 override def legalize(enumeration: CSREnumType): CSREnumType = { 198 val res = WireInit(enumeration) 199 when(!enumeration.isLegal){ 200 res := Disabled.asUInt 201 } 202 res 203 } 204} 205 206object TrigAction extends CSREnum with WARLApply { 207 val BreakpointExp = Value(0.U) // raise breakpoint exception 208 val DebugMode = Value(1.U) // enter debug mode 209 val TraceOn = Value(2.U) 210 val TraceOff = Value(3.U) 211 val TraceNotify = Value(4.U) 212 213 override def isLegal(enumeration: CSREnumType, dmode: Bool): Bool = enumeration.isOneOf(BreakpointExp) || enumeration.isOneOf(DebugMode) && dmode 214 215 override def legalize(enumeration: CSREnumType, dmode: Bool): CSREnumType = { 216 val res = WireInit(enumeration) 217 when(!enumeration.isLegal(dmode)){ 218 res := BreakpointExp 219 } 220 res.asInstanceOf[CSREnumType] 221 } 222} 223 224object TrigMatch extends CSREnum with WARLApply { 225 val EQ = Value(0.U) 226 val NAPOT = Value(1.U) 227 val GE = Value(2.U) 228 val LT = Value(3.U) 229 val MASK_LO = Value(4.U) 230 val MASK_HI = Value(5.U) 231 val NE = Value(8.U) // not eq 232 val NNAPOT = Value(9.U) // not napot 233 val NMASK_LO = Value(12.U) // not mask low 234 val NMASK_HI = Value(13.U) // not mask high 235 def isRVSpecLegal(enumeration: CSREnumType) : Bool = enumeration.isOneOf( 236 EQ, NAPOT, GE, LT, MASK_LO, MASK_HI, 237 NE, NNAPOT, NMASK_LO, NMASK_HI, 238 ) 239 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(EQ, GE, LT) 240 241 override def legalize(enumeration: CSREnumType): CSREnumType = { 242 val res = WireInit(enumeration) 243 when(!enumeration.isLegal){ 244 res := EQ 245 } 246 res.asInstanceOf[CSREnumType] 247 } 248} 249 250 251// tdata2 252class Tdata2Bundle extends OneFieldBundle 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 OneFieldBundle 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 298object DcsrDebugVer extends CSREnum with ROApply { 299 val None = Value(0.U) 300 val Spec = Value(4.U) 301 val Custom = Value(15.U) 302} 303 304object DcsrCause extends CSREnum with ROApply { 305 val None = Value(0.U) 306 val Ebreak = Value(1.U) 307 val Trigger = Value(2.U) 308 val Haltreq = Value(3.U) 309 val Step = Value(4.U) 310 val Resethaltreq = Value(5.U) 311 val Group = Value(6.U) 312} 313 314trait HasTdataSink { self: CSRModule[_] => 315 val tdataRead = IO(Input(new Bundle { 316 val tdata1 = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width 317 val tdata2 = UInt(XLEN.W) 318 })) 319} 320trait HasdebugModeBundle { self: CSRModule[_] => 321 val debugMode = IO(Input(Bool())) 322 val chainable = IO(Input(Bool())) 323} 324 325/** 326 * debug Module MMIO Addr 327 */ 328trait DebugMMIO { 329 implicit val p: Parameters 330 331 def debugMMIO = p(DebugModuleKey).get 332 333 def BASE = debugMMIO.baseAddress 334 def DebugEntry = BASE + 0x800 335 def DebugException = BASE + 0x808 336 def HALTED = BASE + 0x100 337 def GOING = BASE + 0x104 338 def RESUMING = BASE + 0x108 339 def EXCEPTION = BASE + 0x10C 340 def WHERETO = BASE + 0x300 341 def DATA = BASE + 0x380 342 def IMPEBREAK = DATA - 0x4 343 def PROGBUF = DATA - 4 * debugMMIO.nProgramBufferWords 344 def ABSTRACT = PROGBUF - 4 * (if(debugMMIO.atzero) 2 else 5) 345 def FLAGS = BASE + 0x400 346} 347 348object TriggerUtil { 349 /** 350 * Check if chain vector is legal 351 * @param chainVec 352 * @param chainLen 353 * @return true.B if the max length of chain don't exceed the permitted length 354 */ 355 def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = { 356 !ConsecutiveOnes(chainVec, chainLen) 357 } 358}