1
0

RocketTile: Create a wrapper for SyncRocketTile as well (#616)

* RocketTile: Create a wrapper for SyncRocketTile as well

There is no guarantee that debugInterrupt is synchronous
to tlClk, even though it is true in the current implementation.
It will not be true in future implementations, as decoupling
this allows the debugInterrupt to be asserted across tlClk
gating/reset scenarios.

Therefore, even for SyncRocketTile, the debug interrupt needs to be
synchronized to coreClk, and for RationalRocketTile, 1 cycle
of synchronization is not sufficient.

Even though other interrupts may be synchronized, we just
synchronize them all to simplify the code at the expense of
a few cycles latency.

It could still be nice to use a parameter vs hard coding "3".

* RocketTile: Actually use the SyncRocketTile wrapper to get properly synchronized resets.
This commit is contained in:
Megan Wachs 2017-03-27 02:45:37 -07:00 committed by Wesley W. Terpstra
parent 722b0d521f
commit 08c4f7cea6
2 changed files with 43 additions and 7 deletions

View File

@ -44,18 +44,18 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
crossing match {
case Synchronous => {
val tile = LazyModule(new RocketTile(c, i)(pWithExtra))
val wrapper = LazyModule(new SyncRocketTile(c, i)(pWithExtra))
val buffer = LazyModule(new TLBuffer)
val fixer = LazyModule(new TLFIFOFixer)
buffer.node :=* tile.masterNode
buffer.node :=* wrapper.masterNode
fixer.node :=* buffer.node
l1tol2.node :=* fixer.node
tile.slaveNode :*= cbus.node
tile.intNode := intBar.intnode
wrapper.slaveNode :*= cbus.node
wrapper.intNode := intBar.intnode
(io: HasRocketTilesBundle) => {
// leave clock as default (simpler for hierarchical PnR)
tile.module.io.hartid := UInt(i)
tile.module.io.resetVector := io.resetVector
wrapper.module.io.hartid := UInt(i)
wrapper.module.io.resetVector := io.resetVector
debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
}
}

View File

@ -154,6 +154,38 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
ptw.io.requestor <> ptwPorts
}
class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp, hartid))
val masterNode = TLOutputNode()
masterNode :=* rocket.masterNode
val slaveNode = TLInputNode()
rocket.slaveNode :*= slaveNode
val intNode = IntInputNode()
// Some interrupt sources may be completely asynchronous, even
// if tlClk and coreClk are the same (e.g. Debug Interrupt, which
// is coming directly from e.g. TCK)
val xing = LazyModule(new IntXing(3))
rocket.intNode := xing.intnode
xing.intnode := intNode
lazy val module = new LazyModuleImp(this) {
val io = new Bundle {
val master = masterNode.bundleOut
val slave = slaveNode.bundleIn
val interrupts = intNode.bundleIn
val hartid = UInt(INPUT, p(XLen))
val resetVector = UInt(INPUT, p(XLen))
}
// signals that do not change:
rocket.module.io.hartid := io.hartid
rocket.module.io.resetVector := io.resetVector
}
}
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp, hartid))
@ -200,7 +232,11 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
sink.node :*= slaveNode
val intNode = IntInputNode()
val xing = LazyModule(new IntXing(1))
// Some interrupt sources may be completely asynchronous, even
// if tlClk and coreClk are related (e.g. Debug Interrupt, which
// is coming directly from e.g. TCK)
val xing = LazyModule(new IntXing(3))
rocket.intNode := xing.intnode
xing.intnode := intNode