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