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 { crossing match {
case Synchronous => { case Synchronous => {
val tile = LazyModule(new RocketTile(c, i)(pWithExtra)) val wrapper = LazyModule(new SyncRocketTile(c, i)(pWithExtra))
val buffer = LazyModule(new TLBuffer) val buffer = LazyModule(new TLBuffer)
val fixer = LazyModule(new TLFIFOFixer) val fixer = LazyModule(new TLFIFOFixer)
buffer.node :=* tile.masterNode buffer.node :=* wrapper.masterNode
fixer.node :=* buffer.node fixer.node :=* buffer.node
l1tol2.node :=* fixer.node l1tol2.node :=* fixer.node
tile.slaveNode :*= cbus.node wrapper.slaveNode :*= cbus.node
tile.intNode := intBar.intnode wrapper.intNode := intBar.intnode
(io: HasRocketTilesBundle) => { (io: HasRocketTilesBundle) => {
// leave clock as default (simpler for hierarchical PnR) // leave clock as default (simpler for hierarchical PnR)
tile.module.io.hartid := UInt(i) wrapper.module.io.hartid := UInt(i)
tile.module.io.resetVector := io.resetVector wrapper.module.io.resetVector := io.resetVector
debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i) 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 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 { class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp, hartid)) val rocket = LazyModule(new RocketTile(rtp, hartid))
@ -200,7 +232,11 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
sink.node :*= slaveNode sink.node :*= slaveNode
val intNode = IntInputNode() 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 rocket.intNode := xing.intnode
xing.intnode := intNode xing.intnode := intNode