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