Skip to content

Commit

Permalink
Merge pull request #3281 from chipsalliance/mergify/bp/master/pr-3279
Browse files Browse the repository at this point in the history
Relax dependencies on HasPeripheryDebug (backport #3279)
  • Loading branch information
jerryz123 authored Feb 28, 2023
2 parents 6b9fd53 + bc0a640 commit 885f241
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 45 deletions.
70 changes: 37 additions & 33 deletions src/main/scala/devices/debug/Periphery.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import freechips.rocketchip.jtag._
import freechips.rocketchip.util._
import freechips.rocketchip.prci.{ClockSinkParameters, ClockSinkNode}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts.{NullIntSyncSource}

/** Protocols used for communicating with external debugging tools */
sealed trait DebugExportProtocol
Expand Down Expand Up @@ -71,16 +72,16 @@ class ResetCtrlIO(val nComponents: Int)(implicit val p: Parameters) extends Bund
*/

trait HasPeripheryDebug { this: BaseSubsystem =>
private val tlbus = locateTLBusWrapper(p(ExportDebug).slaveWhere)
private lazy val tlbus = locateTLBusWrapper(p(ExportDebug).slaveWhere)

val debugCustomXbarOpt = p(DebugModuleKey).map(params => LazyModule( new DebugCustomXbar(outputRequiresInput = false)))
val apbDebugNodeOpt = p(ExportDebug).apb.option(APBMasterNode(Seq(APBMasterPortParameters(Seq(APBMasterParameters("debugAPB"))))))
lazy val debugCustomXbarOpt = p(DebugModuleKey).map(params => LazyModule( new DebugCustomXbar(outputRequiresInput = false)))
lazy val apbDebugNodeOpt = p(ExportDebug).apb.option(APBMasterNode(Seq(APBMasterPortParameters(Seq(APBMasterParameters("debugAPB"))))))
val debugTLDomainOpt = p(DebugModuleKey).map { _ =>
val domain = ClockSinkNode(Seq(ClockSinkParameters()))
domain := tlbus.fixedClockNode
domain
}
val debugOpt = p(DebugModuleKey).map { params =>
lazy val debugOpt = p(DebugModuleKey).map { params =>
val tlDM = LazyModule(new TLDebugModule(tlbus.beatBytes))

tlDM.node := tlbus.coupleTo("debug"){ TLFragmenter(tlbus) := _ }
Expand All @@ -97,62 +98,65 @@ trait HasPeripheryDebug { this: BaseSubsystem =>
}
tlDM
}
}

trait HasPeripheryDebugModuleImp extends LazyModuleImp {
val outer: HasPeripheryDebug
lazy val debugNode = debugOpt.map(_.intnode).getOrElse(NullIntSyncSource())

val psd = IO(new PSDIO)
val psd = InModuleBody {
val psd = IO(new PSDIO)
psd
}

val resetctrl = outer.debugOpt.map { outerdebug =>
outerdebug.module.io.tl_reset := outer.debugTLDomainOpt.get.in.head._1.reset
outerdebug.module.io.tl_clock := outer.debugTLDomainOpt.get.in.head._1.clock
val resetctrl = IO(new ResetCtrlIO(outerdebug.dmOuter.dmOuter.intnode.edges.out.size))
outerdebug.module.io.hartIsInReset := resetctrl.hartIsInReset
resetctrl.hartResetReq.foreach { rcio => outerdebug.module.io.hartResetReq.foreach { rcdm => rcio := rcdm }}
resetctrl
val resetctrl = InModuleBody {
debugOpt.map { debug =>
debug.module.io.tl_reset := debugTLDomainOpt.get.in.head._1.reset
debug.module.io.tl_clock := debugTLDomainOpt.get.in.head._1.clock
val resetctrl = IO(new ResetCtrlIO(debug.dmOuter.dmOuter.intnode.edges.out.size))
debug.module.io.hartIsInReset := resetctrl.hartIsInReset
resetctrl.hartResetReq.foreach { rcio => debug.module.io.hartResetReq.foreach { rcdm => rcio := rcdm }}
resetctrl
}
}

// noPrefix is workaround https://github.com/freechipsproject/chisel3/issues/1603
val debug = noPrefix(outer.debugOpt.map { outerdebug =>
val debug = InModuleBody { noPrefix(debugOpt.map { debugmod =>
val debug = IO(new DebugIO)

require(!(debug.clockeddmi.isDefined && debug.systemjtag.isDefined),
"You cannot have both DMI and JTAG interface in HasPeripheryDebugModuleImp")
"You cannot have both DMI and JTAG interface in HasPeripheryDebug")

require(!(debug.clockeddmi.isDefined && debug.apb.isDefined),
"You cannot have both DMI and APB interface in HasPeripheryDebugModuleImp")
"You cannot have both DMI and APB interface in HasPeripheryDebug")

require(!(debug.systemjtag.isDefined && debug.apb.isDefined),
"You cannot have both APB and JTAG interface in HasPeripheryDebugModuleImp")
"You cannot have both APB and JTAG interface in HasPeripheryDebug")

debug.clockeddmi.foreach { dbg => outerdebug.module.io.dmi.get <> dbg }
debug.clockeddmi.foreach { dbg => debugmod.module.io.dmi.get <> dbg }

(debug.apb
zip outer.apbDebugNodeOpt
zip outerdebug.module.io.apb_clock
zip outerdebug.module.io.apb_reset).foreach {
zip apbDebugNodeOpt
zip debugmod.module.io.apb_clock
zip debugmod.module.io.apb_reset).foreach {
case (((io, apb), c ), r) =>
apb.out(0)._1 <> io
c:= io.clock
r:= io.reset
}

outerdebug.module.io.debug_reset := debug.reset
outerdebug.module.io.debug_clock := debug.clock
debugmod.module.io.debug_reset := debug.reset
debugmod.module.io.debug_clock := debug.clock

debug.ndreset := outerdebug.module.io.ctrl.ndreset
debug.dmactive := outerdebug.module.io.ctrl.dmactive
outerdebug.module.io.ctrl.dmactiveAck := debug.dmactiveAck
debug.extTrigger.foreach { x => outerdebug.module.io.extTrigger.foreach {y => x <> y}}
debug.ndreset := debugmod.module.io.ctrl.ndreset
debug.dmactive := debugmod.module.io.ctrl.dmactive
debugmod.module.io.ctrl.dmactiveAck := debug.dmactiveAck
debug.extTrigger.foreach { x => debugmod.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"
outerdebug.module.io.ctrl.debugUnavail.foreach { _ := false.B }
debugmod.module.io.ctrl.debugUnavail.foreach { _ := false.B }

debug
})
})}

val dtm = debug.flatMap(_.systemjtag.map(instantiateJtagDTM(_)))
val dtm = InModuleBody { debug.flatMap(_.systemjtag.map(instantiateJtagDTM(_))) }

def instantiateJtagDTM(sj: SystemJTAGIO): DebugTransportModuleJTAG = {

Expand All @@ -168,7 +172,7 @@ trait HasPeripheryDebugModuleImp extends LazyModuleImp {
dtm.io.jtag_version := sj.version
dtm.rf_reset := sj.reset

outer.debugOpt.map { outerdebug =>
debugOpt.map { outerdebug =>
outerdebug.module.io.dmi.get.dmi <> dtm.io.dmi
outerdebug.module.io.dmi.get.dmiClock := sj.jtag.TCK
outerdebug.module.io.dmi.get.dmiReset := sj.reset
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/groundtest/GroundTestSubsystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import freechips.rocketchip.diplomacy.{AddressSet, LazyModule}
import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
import freechips.rocketchip.subsystem.{BaseSubsystem, BaseSubsystemModuleImp, HasTiles, CanHaveMasterAXI4MemPort}
import freechips.rocketchip.tilelink.{TLRAM, TLFragmenter}
import freechips.rocketchip.interrupts.{NullIntSyncSource}

class GroundTestSubsystem(implicit p: Parameters)
extends BaseSubsystem
Expand All @@ -25,6 +26,9 @@ class GroundTestSubsystem(implicit p: Parameters)

val tileStatusNodes = tiles.collect { case t: GroundTestTile => t.statusNode.makeSink() }

// no debug module
val debugNode = NullIntSyncSource()

override lazy val module = new GroundTestSubsystemModuleImp(this)
}

Expand Down
8 changes: 7 additions & 1 deletion src/main/scala/interrupts/NullIntSource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p:
}

object NullIntSource {
def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntNode = {
def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntOutwardNode = {
val null_int_source = LazyModule(new NullIntSource(num, ports, sources))
null_int_source.intnode
}
}

object NullIntSyncSource {
def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntSyncOutwardNode = {
IntSyncCrossingSource() := NullIntSource(num, ports, sources)
}
}
4 changes: 4 additions & 0 deletions src/main/scala/interrupts/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ package object interrupts
type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
type IntNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]

type IntSyncInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]
type IntSyncOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]
type IntSyncNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]

implicit class IntClockDomainCrossing(private val x: HasClockDomainCrossing) extends AnyVal {
def crossIn (n: IntInwardNode) (implicit valName: ValName) = IntInwardClockCrossingHelper(valName.name, x, n)
def crossOut(n: IntOutwardNode)(implicit valName: ValName) = IntOutwardClockCrossingHelper(valName.name, x, n)
Expand Down
13 changes: 5 additions & 8 deletions src/main/scala/subsystem/HasTiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package freechips.rocketchip.subsystem
import chisel3._
import chisel3.dontTouch
import org.chipsalliance.cde.config.{Field, Parameters}
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
import freechips.rocketchip.devices.tilelink.{BasicBusBlocker, BasicBusBlockerParams, CLINTConsts, PLICKey, CanHavePeripheryPLIC, CanHavePeripheryCLINT}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
Expand Down Expand Up @@ -102,7 +101,6 @@ case class TileSlavePortParams(
trait HasTileInterruptSources
extends CanHavePeripheryPLIC
with CanHavePeripheryCLINT
with HasPeripheryDebug
with InstantiatesTiles
{ this: BaseSubsystem => // TODO ideally this bound would be softened to LazyModule
/** meipNode is used to create a single bit subsystem input in Configs without a PLIC */
Expand Down Expand Up @@ -230,7 +228,9 @@ trait DefaultTileContextType
with HasTileInterruptSources
with HasTileNotificationSinks
with HasTileInputConstants
{ this: BaseSubsystem => } // TODO: ideally this bound would be softened to LazyModule
{ this: BaseSubsystem =>
val debugNode: IntSyncOutwardNode
} // TODO: ideally this bound would be softened to LazyModule

/** Standardized interface by which parameterized tiles can be attached to contexts containing interconnect resources.
*
Expand Down Expand Up @@ -291,10 +291,7 @@ trait CanAttachTile {
// we stub out missing interrupts with constant sources here.

// 1. Debug interrupt is definitely asynchronous in all cases.
domain.tile.intInwardNode :=
context.debugOpt
.map { domain { IntSyncAsyncCrossingSink(3) } := _.intnode }
.getOrElse { NullIntSource() }
domain.tile.intInwardNode := domain { IntSyncAsyncCrossingSink(3) } := context.debugNode

// 2. The CLINT and PLIC output interrupts are synchronous to the TileLink bus clock,
// so might need to be synchronized depending on the Tile's crossing type.
Expand Down Expand Up @@ -440,7 +437,7 @@ trait HasTiles extends InstantiatesTiles with HasCoreMonitorBundles with Default
}

/** Provides some Chisel connectivity to certain tile IOs */
trait HasTilesModuleImp extends LazyModuleImp with HasPeripheryDebugModuleImp {
trait HasTilesModuleImp extends LazyModuleImp {
val outer: HasTiles with HasTileInterruptSources with HasTileInputConstants

val reset_vector = outer.tileResetVectorIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"reset_vector_$i") }
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/subsystem/RocketSubsystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing}
import freechips.rocketchip.tile._
import freechips.rocketchip.devices.debug.{HasPeripheryDebug}

case class RocketCrossingParams(
crossingType: ClockCrossingType = SynchronousCrossing(),
Expand All @@ -29,7 +30,7 @@ trait HasRocketTiles extends HasTiles { this: BaseSubsystem =>
}).toList
}

class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem with HasRocketTiles {
class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem with HasRocketTiles with HasPeripheryDebug {
override lazy val module = new RocketSubsystemModuleImp(this)
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/system/TestHarness.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestHarness()(implicit p: Parameters) extends Module {
val dut = Module(ldut.module)

// Allow the debug ndreset to reset the dut, but not until the initial reset has completed
dut.reset := (reset.asBool | dut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool
dut.reset := (reset.asBool | ldut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool

dut.dontTouchPorts()
dut.tieOffInterrupts()
Expand All @@ -34,5 +34,5 @@ class TestHarness()(implicit p: Parameters) extends Module {
a.b.ready := false.B
})
//ldut.l2_frontend_bus_axi4.foreach(_.tieoff)
Debug.connectDebug(dut.debug, dut.resetctrl, dut.psd, clock, reset.asBool, io.success)
Debug.connectDebug(ldut.debug, ldut.resetctrl, ldut.psd, clock, reset.asBool, io.success)
}

0 comments on commit 885f241

Please sign in to comment.