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:
parent
722b0d521f
commit
08c4f7cea6
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user