Debug: Added halt groups. (#1744)
This commit is contained in:
parent
5a84844360
commit
8ce3887c78
|
@ -106,6 +106,8 @@ case class DebugModuleParams (
|
|||
maxSupportedSBAccess : Int = 32,
|
||||
supportQuickAccess : Boolean = false,
|
||||
supportHartArray : Boolean = true,
|
||||
nHaltGroups : Int = 1,
|
||||
nExtTriggers : Int = 0,
|
||||
hasImplicitEbreak : Boolean = false
|
||||
) {
|
||||
|
||||
|
@ -114,6 +116,9 @@ case class DebugModuleParams (
|
|||
require ((nAbstractDataWords > 0) && (nAbstractDataWords <= 16), s"Legal nAbstractDataWords is 0-16, not ${nAbstractDataWords}")
|
||||
require ((nProgramBufferWords >= 0) && (nProgramBufferWords <= 16), s"Legal nProgramBufferWords is 0-16, not ${nProgramBufferWords}")
|
||||
|
||||
require (nHaltGroups < 32, s"Legal nHaltGroups is 0-31, not ${nHaltGroups}")
|
||||
require (nExtTriggers <= 16, s"Legal nExtTriggers is 0-16, not ${nExtTriggers}")
|
||||
|
||||
if (supportQuickAccess) {
|
||||
// TODO: Check that quick access requirements are met.
|
||||
}
|
||||
|
@ -145,6 +150,21 @@ case class DebugModuleHartSelFuncs (
|
|||
|
||||
case object DebugModuleHartSelKey extends Field(DebugModuleHartSelFuncs())
|
||||
|
||||
class DebugExtTriggerOut (nExtTriggers: Int) extends Bundle {
|
||||
val req = Vec(nExtTriggers, Bool()).asOutput
|
||||
val ack = Vec(nExtTriggers, Bool()).asInput
|
||||
}
|
||||
|
||||
class DebugExtTriggerIn (nExtTriggers: Int) extends Bundle {
|
||||
val req = Vec(nExtTriggers, Bool()).asInput
|
||||
val ack = Vec(nExtTriggers, Bool()).asOutput
|
||||
}
|
||||
|
||||
class DebugExtTriggerIO () (implicit val p: Parameters) extends ParameterizedBundle()(p) {
|
||||
val out = new DebugExtTriggerOut(p(DebugModuleParams).nExtTriggers)
|
||||
val in = new DebugExtTriggerIn (p(DebugModuleParams).nExtTriggers)
|
||||
}
|
||||
|
||||
// *****************************************
|
||||
// Module Interfaces
|
||||
//
|
||||
|
@ -255,6 +275,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||
val io = IO(new Bundle {
|
||||
val ctrl = (new DebugCtrlBundle(nComponents))
|
||||
val innerCtrl = new DecoupledIO(new DebugInternalBundle(nComponents))
|
||||
val hgDebugInt = Vec(nComponents, Bool()).asInput
|
||||
})
|
||||
|
||||
//----DMCONTROL (The whole point of 'Outer' is to maintain this register on dmiClock (e.g. TCK) domain, so that it
|
||||
|
@ -377,7 +398,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||
val tempMaskReg = HAMASKReg.asUInt.asBools
|
||||
when (HAWINDOWWrEn && (ii.U === HAWINDOWSELReg.hawindowsel)) {
|
||||
hamask(ii*haWindowSize + jj) := tempWrData(jj)
|
||||
}.otherwise {
|
||||
}.otherwise {
|
||||
hamask(ii*haWindowSize + jj) := tempMaskReg(jj)
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +437,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||
|
||||
val (intnode_out, _) = intnode.out.unzip
|
||||
for (component <- 0 until nComponents) {
|
||||
intnode_out(component)(0) := debugIntRegs(component)
|
||||
intnode_out(component)(0) := debugIntRegs(component) | io.hgDebugInt(component)
|
||||
}
|
||||
|
||||
// Halt request registers are set & cleared by writes to DMCONTROL.haltreq
|
||||
|
@ -432,7 +453,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||
debugIntNxt(component) := false.B
|
||||
}. otherwise {
|
||||
when (DMCONTROLWrEn && ((DMCONTROLWrData.hartsello === component.U)
|
||||
|| (if (supportHartArray) DMCONTROLWrData.hasel && hamask(component) else false.B))) {
|
||||
|| (if (supportHartArray) DMCONTROLWrData.hasel && hamask(component) else false.B))) {
|
||||
debugIntNxt(component) := DMCONTROLWrData.haltreq
|
||||
}
|
||||
}
|
||||
|
@ -474,13 +495,14 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
|
|||
val dmi = new DMIIO()(p).flip()
|
||||
val ctrl = new DebugCtrlBundle(nComponents)
|
||||
val innerCtrl = new AsyncBundle(new DebugInternalBundle(nComponents), AsyncQueueParams.singleton())
|
||||
val hgDebugInt = Vec(nComponents, Bool()).asInput
|
||||
})
|
||||
|
||||
dmi2tl.module.io.dmi <> io.dmi
|
||||
|
||||
io.ctrl <> dmOuter.module.io.ctrl
|
||||
io.innerCtrl := ToAsyncBundle(dmOuter.module.io.innerCtrl, AsyncQueueParams.singleton())
|
||||
|
||||
dmOuter.module.io.hgDebugInt := io.hgDebugInt
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,11 +543,16 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
|
|||
val nComponents = getNComponents()
|
||||
Annotated.params(this, cfg)
|
||||
val supportHartArray = cfg.supportHartArray & (nComponents > 1)
|
||||
val nExtTriggers = cfg.nExtTriggers
|
||||
val nHaltGroups = if ((nComponents > 1) | (nExtTriggers > 1)) cfg.nHaltGroups
|
||||
else 0 // no halt groups possible if single hart with no external triggers
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val dmactive = Bool(INPUT)
|
||||
val innerCtrl = (new DecoupledIO(new DebugInternalBundle(nComponents))).flip
|
||||
val debugUnavail = Vec(nComponents, Bool()).asInput
|
||||
val hgDebugInt = Vec(nComponents, Bool()).asOutput
|
||||
val extTrigger = (nExtTriggers > 0).option(new DebugExtTriggerIO())
|
||||
})
|
||||
|
||||
|
||||
|
@ -543,6 +570,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
|
|||
//--------------------------------------------------------------
|
||||
|
||||
require (cfg.supportQuickAccess == false, "No Quick Access support yet")
|
||||
require ((nHaltGroups > 0) || (nExtTriggers == 0), "External triggers require at least 1 halt group")
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Register & Wire Declarations (which need to be pre-declared)
|
||||
|
@ -643,8 +671,133 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
|
|||
}
|
||||
}
|
||||
|
||||
//----DMCS2 (Halt Groups)
|
||||
|
||||
val DMCS2RdData = Wire(init = (new DMCS2Fields()).fromBits(0.U))
|
||||
val DMCS2WrDataVal = Wire(init = 0.U(32.W))
|
||||
val DMCS2WrEn = Wire(init = false.B)
|
||||
val DMCS2RdEn = Wire(init = false.B)
|
||||
val hgDebugInt = Wire(Vec.fill(nComponents){false.B})
|
||||
|
||||
if (nHaltGroups > 0) {
|
||||
val DMCS2WrData = (new DMCS2Fields()).fromBits(DMCS2WrDataVal)
|
||||
val hgBits = log2Up(nHaltGroups)
|
||||
// hgParticipate: Each entry indicates which hg that entity belongs to (1 to nHartGroups). 0 means no hg assigned.
|
||||
val hgParticipateHart = RegInit(Vec(Seq.fill(nComponents)(0.U(hgBits.W))))
|
||||
val hgParticipateTrig = if (nExtTriggers > 0) RegInit(Vec(Seq.fill(nExtTriggers)(0.U(hgBits.W)))) else Nil
|
||||
|
||||
for (component <- 0 until nComponents) {
|
||||
when (~io.dmactive) {
|
||||
hgParticipateHart(component) := 0.U
|
||||
}.otherwise {
|
||||
when (DMCS2WrEn & DMCS2WrData.hgwrite & ~DMCS2WrData.hgselect &
|
||||
hamaskFull(component) & (DMCS2WrData.haltgroup <= nHaltGroups.U)) {
|
||||
hgParticipateHart(component) := DMCS2WrData.haltgroup
|
||||
}
|
||||
}
|
||||
}
|
||||
DMCS2RdData.haltgroup := hgParticipateHart(selectedHartReg)
|
||||
|
||||
if (nExtTriggers > 0) {
|
||||
val hgSelect = RegInit(false.B)
|
||||
|
||||
when (~io.dmactive) {
|
||||
hgSelect := false.B
|
||||
}.otherwise {
|
||||
when (DMCS2WrEn) {
|
||||
hgSelect := DMCS2WrData.hgselect
|
||||
}
|
||||
}
|
||||
|
||||
for (trigger <- 0 until nExtTriggers) {
|
||||
when (~io.dmactive) {
|
||||
hgParticipateTrig(trigger) := 0.U
|
||||
}.otherwise {
|
||||
when (DMCS2WrEn & DMCS2WrData.hgwrite & DMCS2WrData.hgselect &
|
||||
(DMCS2WrData.exttrigger === trigger.U) & (DMCS2WrData.haltgroup <= nHaltGroups.U)) {
|
||||
hgParticipateTrig(trigger) := DMCS2WrData.haltgroup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DMCS2RdData.hgselect := hgSelect
|
||||
when (hgSelect) {
|
||||
DMCS2RdData.haltgroup := hgParticipateTrig(0)
|
||||
}
|
||||
|
||||
// If there is only 1 ext trigger, then the exttrigger field is fixed at 0
|
||||
// Otherwise, instantiate a register with only the number of bits required
|
||||
|
||||
if (nExtTriggers > 1) {
|
||||
val trigBits = log2Up(nExtTriggers-1)
|
||||
val hgExtTrigger = RegInit(0.U(trigBits.W))
|
||||
when (~io.dmactive) {
|
||||
hgExtTrigger := 0.U
|
||||
}.otherwise {
|
||||
when (DMCS2WrEn & (DMCS2WrData.exttrigger < nExtTriggers.U)) {
|
||||
hgExtTrigger := DMCS2WrData.exttrigger
|
||||
}
|
||||
}
|
||||
|
||||
DMCS2RdData.exttrigger := hgExtTrigger
|
||||
when (hgSelect) {
|
||||
DMCS2RdData.haltgroup := hgParticipateTrig(hgExtTrigger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Halt group state machine
|
||||
// IDLE: Go to FIRED when any hart in this hg writes to HALTED while its HaltedBitRegs=0
|
||||
// or when any trigin assigned to this hg occurs
|
||||
// FIRED: Back to IDLE when all harts in this hg have set their haltedBitRegs
|
||||
// and all trig out in this hg have been acknowledged
|
||||
|
||||
val hgFired = RegInit(Vec.fill(nHaltGroups+1){false.B})
|
||||
val hgHartFiring = Wire(init = Vec.fill(nHaltGroups+1){false.B}) // which hg's are firing due to hart halting
|
||||
val hgTrigFiring = Wire(init = Vec.fill(nHaltGroups+1){false.B}) // which hg's are firing due to trig in
|
||||
val hgHartsAllHalted = Wire(init = Vec.fill(nHaltGroups+1){false.B}) // in which hg's have all harts halted
|
||||
val hgTrigsAllAcked = Wire(init = Vec.fill(nHaltGroups+1){ true.B}) // in which hg's have all trigouts been acked
|
||||
|
||||
io.extTrigger.foreach {extTrigger =>
|
||||
val trigInReq = SynchronizerShiftReg(extTrigger.in.req, 3, Some("dm_extTriggerInReqSync"))
|
||||
val trigOutAck = SynchronizerShiftReg(extTrigger.out.ack, 3, Some("dm_extTriggerOutAckSync"))
|
||||
for (hg <- 1 to nHaltGroups) {
|
||||
hgTrigFiring(hg) := (trigInReq & ~RegNext(trigInReq) & hgParticipateTrig.map(_ === hg.U)).reduce(_ | _)
|
||||
hgTrigsAllAcked(hg) := (trigOutAck | hgParticipateTrig.map(_ =/= hg.U)).reduce(_ & _)
|
||||
}
|
||||
extTrigger.in.ack := trigInReq // acknowledge all trig in
|
||||
}
|
||||
|
||||
for (hg <- 1 to nHaltGroups) {
|
||||
hgHartFiring(hg) := hartHaltedWrEn & ~haltedBitRegs(hartHaltedId) & (hgParticipateHart(hartSelFuncs.hartIdToHartSel(hartHaltedId)) === hg.U)
|
||||
hgHartsAllHalted(hg) := (haltedBitRegs | hgParticipateHart.map(_ =/= hg.U)).reduce(_ & _)
|
||||
|
||||
when (~io.dmactive) {
|
||||
hgFired(hg) := false.B
|
||||
}.elsewhen (~hgFired(hg) & (hgHartFiring(hg) | hgTrigFiring(hg))) {
|
||||
hgFired(hg) := true.B
|
||||
}.elsewhen ( hgFired(hg) & hgHartsAllHalted(hg) & hgTrigsAllAcked(hg)) {
|
||||
hgFired(hg) := false.B
|
||||
}
|
||||
}
|
||||
|
||||
// For each hg that has fired, assert debug interrupt to each hart in that hg
|
||||
for (component <- 0 until nComponents) {
|
||||
hgDebugInt(component) := hgFired(hgParticipateHart(component))
|
||||
}
|
||||
|
||||
// For each hg that has fired, assert trigger out for all external triggers in that hg
|
||||
io.extTrigger.foreach {extTrigger =>
|
||||
for (trig <- 0 until nExtTriggers) {
|
||||
extTrigger.out.req(trig) := hgFired(hgParticipateTrig(trig))
|
||||
}
|
||||
}
|
||||
}
|
||||
io.hgDebugInt := hgDebugInt
|
||||
|
||||
|
||||
//TODO
|
||||
DMSTATUSRdData.devtreevalid := false.B
|
||||
DMSTATUSRdData.confstrptrvalid := false.B
|
||||
|
||||
DMSTATUSRdData.impebreak := (cfg.hasImplicitEbreak).B
|
||||
|
||||
|
@ -834,6 +987,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
|
|||
val omRegMap = dmiNode.regmap(
|
||||
(DMI_DMSTATUS << 2) -> Seq(RegField.r(32, DMSTATUSRdData.asUInt(), RegFieldDesc("dmi_dmstatus", ""))),
|
||||
//TODO (DMI_CFGSTRADDR0 << 2) -> cfgStrAddrFields,
|
||||
(DMI_DMCS2 << 2) -> (if (nHaltGroups > 0) Seq(RWNotify(32, DMCS2RdData.asUInt(),
|
||||
DMCS2WrDataVal, DMCS2RdEn, DMCS2WrEn, Some(RegFieldDesc("dmi_dmcs2", "", reset=Some(0))))) else Nil),
|
||||
(DMI_HARTINFO << 2) -> Seq(RegField.r(32, HARTINFORdData.asUInt(), RegFieldDesc("dmi_hartinfo", "" /*, reset=Some(HARTINFORdData.litValue)*/))),
|
||||
(DMI_HALTSUM0 << 2) -> Seq(RegField.r(32, HALTSUM0RdData.asUInt(), RegFieldDesc("dmi_haltsum0", ""))),
|
||||
(DMI_HALTSUM1 << 2) -> Seq(RegField.r(32, HALTSUM1RdData.asUInt(), RegFieldDesc("dmi_haltsum1", ""))),
|
||||
|
@ -1213,6 +1368,8 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int, beatByt
|
|||
val innerCtrl = new AsyncBundle(new DebugInternalBundle(getNComponents()), AsyncQueueParams.singleton()).flip
|
||||
// This comes from tlClk domain.
|
||||
val debugUnavail = Vec(getNComponents(), Bool()).asInput
|
||||
val hgDebugInt = Vec(getNComponents(), Bool()).asOutput
|
||||
val extTrigger = (p(DebugModuleParams).nExtTriggers > 0).option(new DebugExtTriggerIO())
|
||||
val psd = new PSDTestMode().asInput
|
||||
})
|
||||
|
||||
|
@ -1232,6 +1389,8 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int, beatByt
|
|||
dmInner.module.io.dmactive := dmactive_synced
|
||||
dmInner.module.io.innerCtrl := FromAsyncBundle(io.innerCtrl)
|
||||
dmInner.module.io.debugUnavail := io.debugUnavail
|
||||
io.hgDebugInt := dmInner.module.io.hgDebugInt
|
||||
io.extTrigger.foreach { x => dmInner.module.io.extTrigger.foreach {y => x <> y}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1286,6 +1445,7 @@ class TLDebugModule(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
|||
val io = IO(new Bundle {
|
||||
val ctrl = new DebugCtrlBundle(nComponents)
|
||||
val dmi = new ClockedDMIIO().flip
|
||||
val extTrigger = (p(DebugModuleParams).nExtTriggers > 0).option(new DebugExtTriggerIO())
|
||||
val psd = new PSDTestMode().asInput
|
||||
})
|
||||
|
||||
|
@ -1296,10 +1456,12 @@ class TLDebugModule(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
|||
dmInner.module.io.innerCtrl := dmOuter.module.io.innerCtrl
|
||||
dmInner.module.io.dmactive := dmOuter.module.io.ctrl.dmactive
|
||||
dmInner.module.io.debugUnavail := io.ctrl.debugUnavail
|
||||
dmOuter.module.io.hgDebugInt := dmInner.module.io.hgDebugInt
|
||||
|
||||
dmInner.module.io.psd <> io.psd
|
||||
|
||||
io.ctrl <> dmOuter.module.io.ctrl
|
||||
io.extTrigger.foreach { x => dmInner.module.io.extTrigger.foreach {y => x <> y}}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class DebugIO(implicit val p: Parameters) extends ParameterizedBundle()(p) with
|
|||
val systemjtag = p(ExportDebugJTAG).option(new SystemJTAGIO)
|
||||
val ndreset = Bool(OUTPUT)
|
||||
val dmactive = Bool(OUTPUT)
|
||||
val extTrigger = (p(DebugModuleParams).nExtTriggers > 0).option(new DebugExtTriggerIO())
|
||||
}
|
||||
|
||||
/** Either adds a JTAG DTM to system, and exports a JTAG interface,
|
||||
|
@ -59,6 +60,7 @@ trait HasPeripheryDebugModuleImp extends LazyModuleImp {
|
|||
|
||||
debug.ndreset := outer.debug.module.io.ctrl.ndreset
|
||||
debug.dmactive := outer.debug.module.io.ctrl.dmactive
|
||||
debug.extTrigger.foreach { x => outer.debug.module.io.extTrigger.foreach {y => x <> y}}
|
||||
|
||||
// TODO in inheriting traits: Set this to something meaningful, e.g. "component is in reset or powered down"
|
||||
outer.debug.module.io.ctrl.debugUnavail.foreach { _ := Bool(false) }
|
||||
|
|
|
@ -6,30 +6,13 @@ import Chisel._
|
|||
// 'make chisel'
|
||||
|
||||
object DMI_RegAddrs {
|
||||
/* The address of this register will not change in the future, because it
|
||||
contains \Fversion. It has changed from version 0.11 of this spec.
|
||||
|
||||
This register reports status for the overall debug module
|
||||
as well as the currently selected harts, as defined in \Fhasel.
|
||||
|
||||
Harts are nonexistent if they will never be part of this system, no
|
||||
matter how long a user waits. Eg. in a simple single-hart system only
|
||||
one hart exists, and all others are nonexistent. Debuggers may assume
|
||||
that a system has no harts with indexes higher than the first
|
||||
nonexistent one.
|
||||
|
||||
Harts are unavailable if they might exist/become available at a later
|
||||
time, or if there are other harts with higher indexes than this one. Eg.
|
||||
in a multi-hart system some might temporarily be powered down, or a
|
||||
system might support hot-swapping harts. Systems with very large number
|
||||
of harts may permanently disable some during manufacturing, leaving
|
||||
holes in the otherwise continuous hart index space. In order to let the
|
||||
debugger discover all harts, they must show up as unavailable even if
|
||||
there is no chance of them ever becoming available.
|
||||
/* This register reports status for the overall Debug Module as well as
|
||||
the currently selected harts, as defined in \Fhasel. Its address will
|
||||
not change in the future, because it contains \Fversion.
|
||||
*/
|
||||
def DMI_DMSTATUS = 0x11
|
||||
|
||||
/* This register controls the overall debug module
|
||||
/* This register controls the overall Debug Module
|
||||
as well as the currently selected harts, as defined in \Fhasel.
|
||||
|
||||
\label{hartsel}
|
||||
|
@ -40,7 +23,24 @@ object DMI_RegAddrs {
|
|||
width of \Fhartsel is called {\tt HARTSELLEN}. It must be at least 0
|
||||
and at most 20. A debugger should discover {\tt HARTSELLEN} by writing
|
||||
all ones to \Fhartsel (assuming the maximum size) and reading back the
|
||||
value to see which bits were actually set.
|
||||
value to see which bits were actually set. Debuggers must not change
|
||||
\Fhartsel while an abstract command is executing.
|
||||
|
||||
\begin{commentary}
|
||||
There are separate \Fsetresethaltreq and \Fclrresethaltreq bits so that
|
||||
it is possible to write \Rdmcontrol without changing the halt-on-reset
|
||||
request bit for each selected hart, when not all selected harts have
|
||||
the same configuration.
|
||||
\end{commentary}
|
||||
|
||||
On any given write, a debugger may only write 1 to at most one of the
|
||||
following bits: \Fresumereq, \Fhartreset, \Fackhavereset,
|
||||
\Fsetresethaltreq, and \Fclrresethaltreq. The others must be written 0.
|
||||
|
||||
\label{resethaltreq}
|
||||
\index{resethaltreq}
|
||||
\Fresethaltreq is an optional internal bit of per-hart state that cannot be
|
||||
read, but can be written with \Fsetresethaltreq and \Fclrresethaltreq.
|
||||
*/
|
||||
def DMI_DMCONTROL = 0x10
|
||||
|
||||
|
@ -74,12 +74,21 @@ object DMI_RegAddrs {
|
|||
*/
|
||||
def DMI_HAWINDOW = 0x15
|
||||
|
||||
/* Writing this register while an abstract command is executing causes
|
||||
\Fcmderr to be set to 1 (busy) if it is 0.
|
||||
|
||||
\begin{commentary}
|
||||
\Fdatacount must be at least 1 to support RV32 harts, 2 to support
|
||||
RV64 harts, or 4 to support RV128 harts.
|
||||
\end{commentary}
|
||||
*/
|
||||
def DMI_ABSTRACTCS = 0x16
|
||||
|
||||
/* Writes to this register cause the corresponding abstract command to be
|
||||
executed.
|
||||
|
||||
Writing while an abstract command is executing causes \Fcmderr to be set.
|
||||
Writing this register while an abstract command is executing causes
|
||||
\Fcmderr to be set to 1 (busy) if it is 0.
|
||||
|
||||
If \Fcmderr is non-zero, writes to this register are ignored.
|
||||
|
||||
|
@ -94,34 +103,37 @@ object DMI_RegAddrs {
|
|||
*/
|
||||
def DMI_COMMAND = 0x17
|
||||
|
||||
/* This register is optional. Including it allows more efficient burst accesses.
|
||||
Debugger can attempt to set bits and read them back to determine if the functionality is supported.
|
||||
/* This register is optional. Including it allows more efficient burst
|
||||
accesses. A debugger can detect whether it is support by setting bits
|
||||
and reading them back.
|
||||
|
||||
Writing this register while an abstract command is executing causes
|
||||
\Fcmderr to be set to 1 (busy) if it is 0.
|
||||
*/
|
||||
def DMI_ABSTRACTAUTO = 0x18
|
||||
|
||||
/* When {\tt devtreevalid} is set, reading this register returns bits 31:0
|
||||
of the Device Tree address. Reading the other {\tt devtreeaddr}
|
||||
/* When \Fconfstrptrvalid is set, reading this register returns bits 31:0
|
||||
of the configuration string pointer. Reading the other {\tt confstrptr}
|
||||
registers returns the upper bits of the address.
|
||||
|
||||
When system bus mastering is implemented, this must be an
|
||||
address that can be used with the System Bus Access module. Otherwise,
|
||||
this must be an address that can be used to access the
|
||||
Device Tree from the hart with ID 0.
|
||||
configuration string from the hart with ID 0.
|
||||
|
||||
If {\tt devtreevalid} is 0, then the {\tt devtreeaddr} registers
|
||||
If \Fconfstrptrvalid is 0, then the {\tt confstrptr} registers
|
||||
hold identifier information which is not
|
||||
further specified in this document.
|
||||
|
||||
The Device Tree itself is described in the RISC-V Privileged
|
||||
Specification.
|
||||
The configuration string itself is described in the Privileged Spec.
|
||||
*/
|
||||
def DMI_DEVTREEADDR0 = 0x19
|
||||
def DMI_CONFSTRPTR0 = 0x19
|
||||
|
||||
def DMI_DEVTREEADDR1 = 0x1a
|
||||
def DMI_CONFSTRPTR1 = 0x1a
|
||||
|
||||
def DMI_DEVTREEADDR2 = 0x1b
|
||||
def DMI_CONFSTRPTR2 = 0x1b
|
||||
|
||||
def DMI_DEVTREEADDR3 = 0x1c
|
||||
def DMI_CONFSTRPTR3 = 0x1c
|
||||
|
||||
/* If there is more than one DM accessible on this DMI, this register
|
||||
contains the base address of the next one in the chain, or 0 if this is
|
||||
|
@ -131,12 +143,12 @@ object DMI_RegAddrs {
|
|||
|
||||
/* \Rdatazero through \Rdataeleven are basic read/write registers that may
|
||||
be read or changed by abstract commands. \Fdatacount indicates how many
|
||||
of them are implemented, starting at \Rsbdatazero, counting up.
|
||||
of them are implemented, starting at \Rdatazero, counting up.
|
||||
Table~\ref{tab:datareg} shows how abstract commands use these
|
||||
registers.
|
||||
|
||||
Accessing these registers while an abstract command is executing causes
|
||||
\Fcmderr to be set.
|
||||
\Fcmderr to be set to 1 (busy) if it is 0.
|
||||
|
||||
Attempts to write them while \Fbusy is set does not change their value.
|
||||
|
||||
|
@ -154,7 +166,7 @@ object DMI_RegAddrs {
|
|||
implemented starting at \Rprogbufzero, counting up.
|
||||
|
||||
Accessing these registers while an abstract command is executing causes
|
||||
\Fcmderr to be set.
|
||||
\Fcmderr to be set to 1 (busy) if it is 0.
|
||||
|
||||
Attempts to write them while \Fbusy is set does not change their value.
|
||||
*/
|
||||
|
@ -162,7 +174,7 @@ object DMI_RegAddrs {
|
|||
|
||||
def DMI_PROGBUF15 = 0x2f
|
||||
|
||||
/* This register serves as a 32-bit serial port to the authentication
|
||||
/* This register serves as a 32-bit serial port to/from the authentication
|
||||
module.
|
||||
|
||||
When \Fauthbusy is clear, the debugger can communicate with the
|
||||
|
@ -171,6 +183,11 @@ object DMI_RegAddrs {
|
|||
*/
|
||||
def DMI_AUTHDATA = 0x30
|
||||
|
||||
/* This register contains DM control and status bits that didn't easily
|
||||
fit in \Rdmcontrol and \Rdmstatus. All are optional.
|
||||
*/
|
||||
def DMI_DMCS2 = 0x32
|
||||
|
||||
/* Each bit in this read-only register indicates whether one specific hart
|
||||
is halted or not. Unavailable/nonexistent harts are not considered to
|
||||
be halted.
|
||||
|
@ -220,13 +237,6 @@ object DMI_RegAddrs {
|
|||
*/
|
||||
def DMI_HALTSUM3 = 0x35
|
||||
|
||||
/* If \Fsbasize is less than 97, then this register is not present.
|
||||
|
||||
When the system bus master is busy, writes to this register will set
|
||||
\Fsbbusyerror and don't do anything else.
|
||||
*/
|
||||
def DMI_SBADDRESS3 = 0x37
|
||||
|
||||
def DMI_SBCS = 0x38
|
||||
|
||||
/* If \Fsbasize is 0, then this register is not present.
|
||||
|
@ -259,6 +269,13 @@ object DMI_RegAddrs {
|
|||
*/
|
||||
def DMI_SBADDRESS2 = 0x3b
|
||||
|
||||
/* If \Fsbasize is less than 97, then this register is not present.
|
||||
|
||||
When the system bus master is busy, writes to this register will set
|
||||
\Fsbbusyerror and don't do anything else.
|
||||
*/
|
||||
def DMI_SBADDRESS3 = 0x37
|
||||
|
||||
/* If all of the {\tt sbaccess} bits in \Rsbcs are 0, then this register
|
||||
is not present.
|
||||
|
||||
|
@ -282,8 +299,10 @@ object DMI_RegAddrs {
|
|||
\begin{steps}{Reads from this register start the following:}
|
||||
\item ``Return'' the data.
|
||||
\item Set \Fsbbusy.
|
||||
\item If \Fsbreadondata is set, perform a system bus read from the
|
||||
address contained in {\tt sbaddress}, placing the result in {\tt
|
||||
sbdata}.
|
||||
\item If \Fsbautoincrement is set, increment {\tt sbaddress}.
|
||||
\item If \Fsbreadondata is set, perform another system bus read.
|
||||
\item Clear \Fsbbusy.
|
||||
\end{steps}
|
||||
|
||||
|
@ -333,29 +352,33 @@ class DMSTATUSFields extends Bundle {
|
|||
|
||||
val reserved1 = UInt(2.W)
|
||||
|
||||
/* This field is 1 when all currently selected harts have been reset but the reset has not been acknowledged.
|
||||
/* This field is 1 when all currently selected harts have been reset
|
||||
and reset has not been acknowledged for any of them.
|
||||
*/
|
||||
val allhavereset = Bool()
|
||||
|
||||
/* This field is 1 when any currently selected hart has been reset but the reset has not been acknowledged.
|
||||
/* This field is 1 when at least one currently selected hart has been
|
||||
reset and reset has not been acknowledged for that hart.
|
||||
*/
|
||||
val anyhavereset = Bool()
|
||||
|
||||
/* This field is 1 when all currently selected harts have acknowledged
|
||||
the previous resume request.
|
||||
their last resume request.
|
||||
*/
|
||||
val allresumeack = Bool()
|
||||
|
||||
/* This field is 1 when any currently selected hart has acknowledged
|
||||
the previous resume request.
|
||||
its last resume request.
|
||||
*/
|
||||
val anyresumeack = Bool()
|
||||
|
||||
/* This field is 1 when all currently selected harts do not exist in this system.
|
||||
/* This field is 1 when all currently selected harts do not exist in
|
||||
this platform.
|
||||
*/
|
||||
val allnonexistent = Bool()
|
||||
|
||||
/* This field is 1 when any currently selected hart does not exist in this system.
|
||||
/* This field is 1 when any currently selected hart does not exist in
|
||||
this platform.
|
||||
*/
|
||||
val anynonexistent = Bool()
|
||||
|
||||
|
@ -383,9 +406,12 @@ class DMSTATUSFields extends Bundle {
|
|||
*/
|
||||
val anyhalted = Bool()
|
||||
|
||||
/* 0 when authentication is required before using the DM. 1 when the
|
||||
authentication check has passed. On components that don't implement
|
||||
authentication, this bit must be preset as 1.
|
||||
/* 0: Authentication is required before using the DM.
|
||||
|
||||
1: The authentication check has passed.
|
||||
|
||||
On components that don't implement authentication, this bit must be
|
||||
preset as 1.
|
||||
*/
|
||||
val authenticated = Bool()
|
||||
|
||||
|
@ -400,15 +426,19 @@ class DMSTATUSFields extends Bundle {
|
|||
*/
|
||||
val authbusy = Bool()
|
||||
|
||||
val reserved2 = UInt(1.W)
|
||||
|
||||
/* 0: \Rdevtreeaddrzero--\Rdevtreeaddrthree hold information which
|
||||
is not relevant to the Device Tree.
|
||||
|
||||
1: \Rdevtreeaddrzero--\Rdevtreeaddrthree registers hold the address of the
|
||||
Device Tree.
|
||||
/* 1 if this Debug Module supports halt-on-reset functionality
|
||||
controllable by the \Fsetresethaltreq and \Fclrresethaltreq bits.
|
||||
0 otherwise.
|
||||
*/
|
||||
val devtreevalid = Bool()
|
||||
val hasresethaltreq = Bool()
|
||||
|
||||
/* 0: \Rconfstrptrzero--\Rconfstrptrthree hold information which
|
||||
is not relevant to the configuration string.
|
||||
|
||||
1: \Rconfstrptrzero--\Rconfstrptrthree hold the address of the
|
||||
configuration string.
|
||||
*/
|
||||
val confstrptrvalid = Bool()
|
||||
|
||||
/* 0: There is no Debug Module present.
|
||||
|
||||
|
@ -427,23 +457,22 @@ class DMSTATUSFields extends Bundle {
|
|||
|
||||
class DMCONTROLFields extends Bundle {
|
||||
|
||||
/* Writes the halt request bit for all currently selected harts.
|
||||
When set to 1, each selected hart will halt if it is not currently
|
||||
halted.
|
||||
/* Writing 0 clears the halt request bit for all currently selected
|
||||
harts. This may cancel outstanding halt requests for those harts.
|
||||
|
||||
Writing 1 or 0 has no effect on a hart which is already halted, but
|
||||
the bit must be cleared to 0 before the hart is resumed.
|
||||
Writing 1 sets the halt request bit for all currently selected
|
||||
harts. Running harts will halt whenever their halt request bit is
|
||||
set.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
val haltreq = Bool()
|
||||
|
||||
/* Writes the resume request bit for all currently selected harts.
|
||||
When set to 1, each selected hart will resume if it is currently
|
||||
halted.
|
||||
/* Writing 1 causes the currently selected harts to resume once, if
|
||||
they are halted when the write occurs. It also clears the resume
|
||||
ack bit for those harts.
|
||||
|
||||
The resume request bit is ignored while the halt request bit is
|
||||
set.
|
||||
\Fresumereq is ignored if \Fhaltreq is set.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
|
@ -453,6 +482,9 @@ class DMCONTROLFields extends Bundle {
|
|||
selected harts. To perform a reset the debugger writes 1, and then
|
||||
writes 0 to deassert the reset signal.
|
||||
|
||||
While this bit is 1, the debugger must not change which harts are
|
||||
selected.
|
||||
|
||||
If this feature is not implemented, the bit always stays 0, so
|
||||
after writing 1 the debugger can read the register back to see if
|
||||
the feature is supported.
|
||||
|
@ -461,8 +493,9 @@ class DMCONTROLFields extends Bundle {
|
|||
*/
|
||||
val hartreset = Bool()
|
||||
|
||||
/* Writing 1 to this bit clears the {\tt havereset} bits for
|
||||
any selected harts.
|
||||
/* 0: No effect.
|
||||
|
||||
1: Clears {\tt havereset} for any selected harts.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
|
@ -470,12 +503,13 @@ class DMCONTROLFields extends Bundle {
|
|||
|
||||
val reserved0 = UInt(1.W)
|
||||
|
||||
/* Selects the definition of currently selected harts.
|
||||
/* Selects the definition of currently selected harts.
|
||||
|
||||
0: There is a single currently selected hart, that selected by \Fhartsel.
|
||||
0: There is a single currently selected hart, that is selected by \Fhartsel.
|
||||
|
||||
1: There may be multiple currently selected harts -- that selected by \Fhartsel,
|
||||
plus those selected by the hart array mask register.
|
||||
1: There may be multiple currently selected harts -- the hart
|
||||
selected by \Fhartsel, plus those selected by the hart array mask
|
||||
register.
|
||||
|
||||
An implementation which does not implement the hart array mask register
|
||||
must tie this field to 0. A debugger which wishes to use the hart array
|
||||
|
@ -494,7 +528,27 @@ class DMCONTROLFields extends Bundle {
|
|||
*/
|
||||
val hartselhi = UInt(10.W)
|
||||
|
||||
val reserved1 = UInt(4.W)
|
||||
val reserved1 = UInt(2.W)
|
||||
|
||||
/* This optional field writes the halt-on-reset request bit for all
|
||||
currently selected harts, unless \Fclrresethaltreq is
|
||||
simultaneously set to 1.
|
||||
When set to 1, each selected hart will halt upon the next deassertion
|
||||
of its reset. The halt-on-reset request bit is not automatically
|
||||
cleared. The debugger must write to \Fclrresethaltreq to clear it.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
|
||||
If \Fhasresethaltreq is 0, this field is not implemented.
|
||||
*/
|
||||
val setresethaltreq = Bool()
|
||||
|
||||
/* This optional field clears the halt-on-reset request bit for all
|
||||
currently selected harts.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
val clrresethaltreq = Bool()
|
||||
|
||||
/* This bit controls the reset signal from the DM to the rest of the
|
||||
system. The signal should reset every part of the system, including
|
||||
|
@ -515,15 +569,16 @@ class DMCONTROLFields extends Bundle {
|
|||
1: The module functions normally.
|
||||
|
||||
No other mechanism should exist that may result in resetting the
|
||||
Debug Module after power up, including the platform's system reset
|
||||
or Debug Transport reset signals.
|
||||
Debug Module after power up, with the possible (but not
|
||||
recommended) exception of a global reset signal that resets the
|
||||
entire platform.
|
||||
|
||||
A debugger may pulse this bit low to get the debug module into a
|
||||
A debugger may pulse this bit low to get the Debug Module into a
|
||||
known state.
|
||||
|
||||
Implementations may use this bit to aid debugging, for example by
|
||||
preventing the Debug Module from being power gated while debugging
|
||||
is active.
|
||||
Implementations may pay attention to this bit to further aid
|
||||
debugging, for example by preventing the Debug Module from being
|
||||
power gated while debugging is active.
|
||||
*/
|
||||
val dmactive = Bool()
|
||||
|
||||
|
@ -542,8 +597,8 @@ class HARTINFOFields extends Bundle {
|
|||
|
||||
val reserved1 = UInt(3.W)
|
||||
|
||||
/* 0: The {\tt data} registers are shadowed in the hart by CSR
|
||||
registers. Each CSR register is XLEN bits in size, and corresponds
|
||||
/* 0: The {\tt data} registers are shadowed in the hart by CSRs.
|
||||
Each CSR is DXLEN bits in size, and corresponds
|
||||
to a single argument, per Table~\ref{tab:datareg}.
|
||||
|
||||
1: The {\tt data} registers are shadowed in the hart's memory map.
|
||||
|
@ -551,7 +606,7 @@ class HARTINFOFields extends Bundle {
|
|||
*/
|
||||
val dataaccess = Bool()
|
||||
|
||||
/* If \Fdataaccess is 0: Number of CSR registers dedicated to
|
||||
/* If \Fdataaccess is 0: Number of CSRs dedicated to
|
||||
shadowing the {\tt data} registers.
|
||||
|
||||
If \Fdataaccess is 1: Number of 32-bit words in the memory map
|
||||
|
@ -577,7 +632,7 @@ class HAWINDOWSELFields extends Bundle {
|
|||
val reserved0 = UInt(17.W)
|
||||
|
||||
/* The high bits of this field may be tied to 0, depending on how large
|
||||
the array mask register is. Eg. on a system with 48 harts only bit 0
|
||||
the array mask register is. E.g.\ on a system with 48 harts only bit 0
|
||||
of this field may actually be writable.
|
||||
*/
|
||||
val hawindowsel = UInt(15.W)
|
||||
|
@ -613,20 +668,26 @@ class ABSTRACTCSFields extends Bundle {
|
|||
they are cleared by writing 1 to them. No abstract command is
|
||||
started until the value is reset to 0.
|
||||
|
||||
This field only contains a valid value if \Fbusy is 0.
|
||||
|
||||
0 (none): No error.
|
||||
|
||||
1 (busy): An abstract command was executing while \Rcommand,
|
||||
\Rabstractcs, \Rabstractauto was written, or when one
|
||||
\Rabstractcs, or \Rabstractauto was written, or when one
|
||||
of the {\tt data} or {\tt progbuf} registers was read or written.
|
||||
This status is only written if \Fcmderr contains 0.
|
||||
|
||||
2 (not supported): The requested command is not supported,
|
||||
regardless of whether the hart is running or not.
|
||||
|
||||
3 (exception): An exception occurred while executing the command
|
||||
(eg. while executing the Program Buffer).
|
||||
(e.g.\ while executing the Program Buffer).
|
||||
|
||||
4 (halt/resume): The abstract command couldn't execute because the
|
||||
hart wasn't in the required state (running/halted).
|
||||
hart wasn't in the required state (running/halted), or unavailable.
|
||||
|
||||
5 (bus): The abstract command failed due to a bus error (e.g.\
|
||||
alignment, access size, or timeout).
|
||||
|
||||
7 (other): The command failed for another reason.
|
||||
*/
|
||||
|
@ -635,7 +696,7 @@ class ABSTRACTCSFields extends Bundle {
|
|||
val reserved3 = UInt(4.W)
|
||||
|
||||
/* Number of {\tt data} registers that are implemented as part of the
|
||||
abstract command interface. Valid sizes are 0 - 12.
|
||||
abstract command interface. Valid sizes are 1 -- 12.
|
||||
*/
|
||||
val datacount = UInt(4.W)
|
||||
|
||||
|
@ -657,21 +718,23 @@ class COMMANDFields extends Bundle {
|
|||
|
||||
class ABSTRACTAUTOFields extends Bundle {
|
||||
|
||||
/* When a bit in this field is 1, read or write accesses to the corresponding {\tt progbuf} word
|
||||
cause the command in \Rcommand to be executed again.
|
||||
/* When a bit in this field is 1, read or write accesses to the
|
||||
corresponding {\tt progbuf} word cause the command in \Rcommand to
|
||||
be executed again.
|
||||
*/
|
||||
val autoexecprogbuf = UInt(16.W)
|
||||
|
||||
val reserved0 = UInt(4.W)
|
||||
|
||||
/* When a bit in this field is 1, read or write accesses to the corresponding {\tt data} word
|
||||
cause the command in \Rcommand to be executed again.
|
||||
/* When a bit in this field is 1, read or write accesses to the
|
||||
corresponding {\tt data} word cause the command in \Rcommand to be
|
||||
executed again.
|
||||
*/
|
||||
val autoexecdata = UInt(12.W)
|
||||
|
||||
}
|
||||
|
||||
class DEVTREEADDR0Fields extends Bundle {
|
||||
class CONFSTRPTR0Fields extends Bundle {
|
||||
|
||||
val addr = UInt(32.W)
|
||||
|
||||
|
@ -701,6 +764,52 @@ class AUTHDATAFields extends Bundle {
|
|||
|
||||
}
|
||||
|
||||
class DMCS2Fields extends Bundle {
|
||||
|
||||
val reserved0 = UInt(21.W)
|
||||
|
||||
/* This field contains the currently selected external trigger.
|
||||
|
||||
If a non-existent trigger value is written here, the hardware will
|
||||
change it to a valid one or 0 if no external triggers exist.
|
||||
*/
|
||||
val exttrigger = UInt(4.W)
|
||||
|
||||
/* When \Fhgselect is 0, contains the halt group of the hart
|
||||
specified by \Fhartsel.
|
||||
|
||||
When \Fhgselect is 1, contains the halt group of the external
|
||||
trigger selected by \Fexttrigger.
|
||||
|
||||
Writes only have an effect if \Fhgwrite is also written 1.
|
||||
|
||||
An implementation may tie any number of upper bits in this field to
|
||||
0. If halt groups aren't implemented, then this entire field
|
||||
is 0.
|
||||
*/
|
||||
val haltgroup = UInt(5.W)
|
||||
|
||||
/* When \Fhgselect is 0, writing 1 changes the halt group of all
|
||||
selected harts to the value written to \Fhaltgroup.
|
||||
|
||||
When \Fhgselect is 1, writing 1 changes the halt group of the
|
||||
external trigger selected by \Fexttrigger to the value written to
|
||||
\Fhaltgroup.
|
||||
|
||||
Writing 0 has no effect.
|
||||
*/
|
||||
val hgwrite = Bool()
|
||||
|
||||
/* 0: Operate on harts.
|
||||
|
||||
1: Operate on external triggers.
|
||||
|
||||
If there are no external triggers, this field must be tied to 0.
|
||||
*/
|
||||
val hgselect = Bool()
|
||||
|
||||
}
|
||||
|
||||
class HALTSUM0Fields extends Bundle {
|
||||
|
||||
val haltsum0 = UInt(32.W)
|
||||
|
@ -725,15 +834,6 @@ class HALTSUM3Fields extends Bundle {
|
|||
|
||||
}
|
||||
|
||||
class SBADDRESS3Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 127:96 of the physical address in {\tt sbaddress} (if
|
||||
the system address bus is that wide).
|
||||
*/
|
||||
val address = UInt(32.W)
|
||||
|
||||
}
|
||||
|
||||
class SBCSFields extends Bundle {
|
||||
|
||||
/* 0: The System Bus interface conforms to mainline drafts of this
|
||||
|
@ -752,8 +852,8 @@ class SBCSFields extends Bundle {
|
|||
already in progress (while \Fsbbusy is set). It remains set until
|
||||
it's explicitly cleared by the debugger.
|
||||
|
||||
While this field is non-zero, no more system bus accesses can be
|
||||
initiated by the debug module.
|
||||
While this field is set, no more system bus accesses can be
|
||||
initiated by the Debug Module.
|
||||
*/
|
||||
val sbbusyerror = Bool()
|
||||
|
||||
|
@ -762,8 +862,9 @@ class SBCSFields extends Bundle {
|
|||
bit goes high immediately when a read or write is requested for any
|
||||
reason, and does not go low until the access is fully completed.
|
||||
|
||||
To avoid race conditions, debuggers must not try to clear \Fsberror
|
||||
until they read \Fsbbusy as 0.
|
||||
Writes to \Rsbcs while \Fsbbusy is high result in undefined
|
||||
behavior. A debugger must not write to \Rsbcs until it reads
|
||||
\Fsbbusy as 0.
|
||||
*/
|
||||
val sbbusy = Bool()
|
||||
|
||||
|
@ -785,7 +886,7 @@ class SBCSFields extends Bundle {
|
|||
4: 128-bit
|
||||
|
||||
If \Fsbaccess has an unsupported value when the DM starts a bus
|
||||
access, the access is not performed and \Fsberror is set to 3.
|
||||
access, the access is not performed and \Fsberror is set to 4.
|
||||
*/
|
||||
val sbaccess = UInt(3.W)
|
||||
|
||||
|
@ -799,13 +900,13 @@ class SBCSFields extends Bundle {
|
|||
*/
|
||||
val sbreadondata = Bool()
|
||||
|
||||
/* When the debug module's system bus
|
||||
master causes a bus error, this field gets set. The bits in this
|
||||
/* When the Debug Module's system bus
|
||||
master encounters an error, this field gets set. The bits in this
|
||||
field remain set until they are cleared by writing 1 to them.
|
||||
While this field is non-zero, no more system bus accesses can be
|
||||
initiated by the debug module.
|
||||
initiated by the Debug Module.
|
||||
|
||||
An implementation may report "Other" (7) for any error condition.
|
||||
An implementation may report ``Other'' (7) for any error condition.
|
||||
|
||||
0: There was no bus error.
|
||||
|
||||
|
@ -874,6 +975,15 @@ class SBADDRESS2Fields extends Bundle {
|
|||
|
||||
}
|
||||
|
||||
class SBADDRESS3Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 127:96 of the physical address in {\tt sbaddress} (if
|
||||
the system address bus is that wide).
|
||||
*/
|
||||
val address = UInt(32.W)
|
||||
|
||||
}
|
||||
|
||||
class SBDATA0Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 31:0 of {\tt sbdata}.
|
||||
|
|
Loading…
Reference in New Issue