1
0

rocket: use diplomatic interrupts

This makes it possible for the PLIC to work with heterogenous cores.
This commit is contained in:
Wesley W. Terpstra 2017-03-02 13:37:25 -08:00
parent d3c5318714
commit 4535de2669
6 changed files with 52 additions and 58 deletions

View File

@ -49,7 +49,6 @@ trait HasCoreplexParameters {
lazy val cbusConfig = p(CBusConfig) lazy val cbusConfig = p(CBusConfig)
lazy val l1tol2Config = p(L1toL2Config) lazy val l1tol2Config = p(L1toL2Config)
lazy val nTiles = tilesParams.size lazy val nTiles = tilesParams.size
lazy val hasSupervisor = tilesParams.exists(_.core.useVM) // TODO ask andrew about this
lazy val l2Config = p(BankedL2Config) lazy val l2Config = p(BankedL2Config)
} }

View File

@ -15,7 +15,7 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork {
val module: CoreplexRISCVPlatformModule val module: CoreplexRISCVPlatformModule
val debug = LazyModule(new TLDebugModule()) val debug = LazyModule(new TLDebugModule())
val plic = LazyModule(new TLPLIC(hasSupervisor, maxPriorities = 7)) val plic = LazyModule(new TLPLIC(maxPriorities = 7))
val clint = LazyModule(new CoreplexLocalInterrupter) val clint = LazyModule(new CoreplexLocalInterrupter)
debug.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) debug.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node)

View File

@ -23,20 +23,6 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
private val crossing = p(RocketCrossing) private val crossing = p(RocketCrossing)
private val configs = p(RocketTilesKey) private val configs = p(RocketTilesKey)
private val rocketTileIntNodes = configs.map { _ => IntInternalOutputNode(IntSinkPortSimple(ports = 2)) }
rocketTileIntNodes.foreach { n =>
n := plic.intnode
n := clint.intnode
}
private def wireInterrupts(x: TileInterrupts, i: Int) {
x.debug := debug.module.io.debugInterrupts(i)
x.meip := rocketTileIntNodes(i).bundleOut(0)(0)
x.seip.foreach { _ := rocketTileIntNodes(i).bundleOut(0)(1) } // optional
x.msip := rocketTileIntNodes(i).bundleOut(1)(0)
x.mtip := rocketTileIntNodes(i).bundleOut(1)(1)
}
val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) => val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) =>
val pWithExtra = p.alterPartial { val pWithExtra = p.alterPartial {
case TileKey => c case TileKey => c
@ -45,6 +31,15 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
} }
// Hack debug interrupt into a node (future debug module should use diplomacy)
val debugNode = IntInternalInputNode(IntSourcePortSimple())
val intBar = LazyModule(new IntXbar)
intBar.intnode := debugNode
intBar.intnode := clint.intnode // msip+mtip
intBar.intnode := plic.intnode // meip
if (c.core.useVM) intBar.intnode := plic.intnode // seip
crossing match { crossing match {
case Synchronous => { case Synchronous => {
val tile = LazyModule(new RocketTile(c, i)(pWithExtra)) val tile = LazyModule(new RocketTile(c, i)(pWithExtra))
@ -52,21 +47,12 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
buffer.node :=* tile.masterNode buffer.node :=* tile.masterNode
l1tol2.node :=* buffer.node l1tol2.node :=* buffer.node
tile.slaveNode :*= cbus.node tile.slaveNode :*= cbus.node
ResourceBinding { tile.intNode := intBar.intnode
rocketTileIntNodes(i).edgesIn(0).source.sources.flatMap(_.resources).foreach { r =>
r.bind(tile.device, ResourceInt(11)) // meip
if (c.core.useVM) r.bind(tile.device, ResourceInt(9)) // seip
}
rocketTileIntNodes(i).edgesIn(1).source.sources.flatMap(_.resources).foreach { r =>
r.bind(tile.device, ResourceInt(3)) // msip
r.bind(tile.device, ResourceInt(7)) // mtip
}
}
(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) tile.module.io.hartid := UInt(i)
tile.module.io.resetVector := io.resetVector tile.module.io.resetVector := io.resetVector
wireInterrupts(tile.module.io.interrupts, i) debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
} }
} }
case Asynchronous(depth, sync) => { case Asynchronous(depth, sync) => {
@ -76,23 +62,14 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
sink.node :=* wrapper.masterNode sink.node :=* wrapper.masterNode
l1tol2.node :=* sink.node l1tol2.node :=* sink.node
wrapper.slaveNode :*= source.node wrapper.slaveNode :*= source.node
wrapper.intNode := intBar.intnode
source.node :*= cbus.node source.node :*= cbus.node
ResourceBinding {
rocketTileIntNodes(i).edgesIn(0).source.sources.flatMap(_.resources).foreach { r =>
r.bind(wrapper.rocket.device, ResourceInt(11)) // meip
if (c.core.useVM) r.bind(wrapper.rocket.device, ResourceInt(9)) // seip
}
rocketTileIntNodes(i).edgesIn(1).source.sources.flatMap(_.resources).foreach { r =>
r.bind(wrapper.rocket.device, ResourceInt(3)) // msip
r.bind(wrapper.rocket.device, ResourceInt(7)) // mtip
}
}
(io: HasRocketTilesBundle) => { (io: HasRocketTilesBundle) => {
wrapper.module.clock := io.tcrs(i).clock wrapper.module.clock := io.tcrs(i).clock
wrapper.module.reset := io.tcrs(i).reset wrapper.module.reset := io.tcrs(i).reset
wrapper.module.io.hartid := UInt(i) wrapper.module.io.hartid := UInt(i)
wrapper.module.io.resetVector := io.resetVector wrapper.module.io.resetVector := io.resetVector
wireInterrupts(wrapper.module.io.interrupts, i) debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
} }
} }
case Rational => { case Rational => {
@ -102,23 +79,14 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
sink.node :=* wrapper.masterNode sink.node :=* wrapper.masterNode
l1tol2.node :=* sink.node l1tol2.node :=* sink.node
wrapper.slaveNode :*= source.node wrapper.slaveNode :*= source.node
wrapper.intNode := intBar.intnode
source.node :*= cbus.node source.node :*= cbus.node
ResourceBinding {
rocketTileIntNodes(i).edgesIn(0).source.sources.flatMap(_.resources).foreach { r =>
r.bind(wrapper.rocket.device, ResourceInt(11)) // meip
if (c.core.useVM) r.bind(wrapper.rocket.device, ResourceInt(9)) // seip
}
rocketTileIntNodes(i).edgesIn(1).source.sources.flatMap(_.resources).foreach { r =>
r.bind(wrapper.rocket.device, ResourceInt(3)) // msip
r.bind(wrapper.rocket.device, ResourceInt(7)) // mtip
}
}
(io: HasRocketTilesBundle) => { (io: HasRocketTilesBundle) => {
wrapper.module.clock := io.tcrs(i).clock wrapper.module.clock := io.tcrs(i).clock
wrapper.module.reset := io.tcrs(i).reset wrapper.module.reset := io.tcrs(i).reset
wrapper.module.io.hartid := UInt(i) wrapper.module.io.hartid := UInt(i)
wrapper.module.io.resetVector := io.resetVector wrapper.module.io.resetVector := io.resetVector
wireInterrupts(wrapper.module.io.interrupts, i) debugNode.bundleOut(0)(0) := debug.module.io.debugInterrupts(i)
} }
} }
} }

View File

@ -87,6 +87,19 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
ResourceBinding { ResourceBinding {
Resource(device, "reg").bind(ResourceInt(BigInt(hartid))) Resource(device, "reg").bind(ResourceInt(BigInt(hartid)))
// debug, msip, mtip, meip, seip offsets in CSRs
val intMap = Seq(65535, 3, 7, 11, 9)
intNode.edgesIn.flatMap(_.source.sources).map { case s =>
for (i <- s.range.start until s.range.end) {
intMap.lift(i).foreach { j =>
s.resources.foreach { r =>
r.bind(device, ResourceInt(j))
}
}
}
}
} }
override lazy val module = new RocketTileModule(this) override lazy val module = new RocketTileModule(this)
@ -100,7 +113,6 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
with CanHaveScratchpadModule { with CanHaveScratchpadModule {
val core = Module(p(BuildCore)(outer.p)) val core = Module(p(BuildCore)(outer.p))
core.io.interrupts := io.interrupts
core.io.hartid := io.hartid core.io.hartid := io.hartid
outer.frontend.module.io.cpu <> core.io.imem outer.frontend.module.io.cpu <> core.io.imem
outer.frontend.module.io.resetVector := io.resetVector outer.frontend.module.io.resetVector := io.resetVector
@ -115,6 +127,13 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
core.io.rocc.interrupt := lr.module.io.core.interrupt core.io.rocc.interrupt := lr.module.io.core.interrupt
} }
// Decode the interrupt vector
core.io.interrupts.debug := io.interrupts(0)(0)
core.io.interrupts.msip := io.interrupts(0)(1)
core.io.interrupts.mtip := io.interrupts(0)(2)
core.io.interrupts.meip := io.interrupts(0)(3)
core.io.interrupts.seip.foreach { _ := io.interrupts(0)(4) }
// TODO eliminate this redundancy // TODO eliminate this redundancy
val h = dcachePorts.size val h = dcachePorts.size
val c = core.dcacheArbPorts val c = core.dcacheArbPorts
@ -139,15 +158,19 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
rocket.slaveNode :*= sink.node rocket.slaveNode :*= sink.node
sink.node :*= slaveNode sink.node :*= slaveNode
val intNode = IntInputNode()
val xing = LazyModule(new IntXing(3))
rocket.intNode := xing.intnode
xing.intnode := intNode
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
val master = masterNode.bundleOut val master = masterNode.bundleOut
val slave = slaveNode.bundleIn val slave = slaveNode.bundleIn
val interrupts = intNode.bundleIn
val hartid = UInt(INPUT, p(XLen)) val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts()(p).asInput
val resetVector = UInt(INPUT, p(XLen)) val resetVector = UInt(INPUT, p(XLen))
} }
rocket.module.io.interrupts := ShiftRegister(io.interrupts, 3)
// signals that do not change: // signals that do not change:
rocket.module.io.hartid := io.hartid rocket.module.io.hartid := io.hartid
rocket.module.io.resetVector := io.resetVector rocket.module.io.resetVector := io.resetVector
@ -167,15 +190,19 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
rocket.slaveNode :*= sink.node rocket.slaveNode :*= sink.node
sink.node :*= slaveNode sink.node :*= slaveNode
val intNode = IntInputNode()
val xing = LazyModule(new IntXing(1))
rocket.intNode := xing.intnode
xing.intnode := intNode
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
val master = masterNode.bundleOut val master = masterNode.bundleOut
val slave = slaveNode.bundleIn val slave = slaveNode.bundleIn
val interrupts = intNode.bundleIn
val hartid = UInt(INPUT, p(XLen)) val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts()(p).asInput
val resetVector = UInt(INPUT, p(XLen)) val resetVector = UInt(INPUT, p(XLen))
} }
rocket.module.io.interrupts := ShiftRegister(io.interrupts, 1)
// signals that do not change: // signals that do not change:
rocket.module.io.hartid := io.hartid rocket.module.io.hartid := io.hartid
rocket.module.io.resetVector := io.resetVector rocket.module.io.resetVector := io.resetVector

View File

@ -53,11 +53,13 @@ trait HasTileLinkMasterPort extends HasTileParameters {
implicit val p: Parameters implicit val p: Parameters
val module: HasTileLinkMasterPortModule val module: HasTileLinkMasterPortModule
val masterNode = TLOutputNode() val masterNode = TLOutputNode()
val intNode = IntSinkNode(IntSinkPortSimple())
} }
trait HasTileLinkMasterPortBundle { trait HasTileLinkMasterPortBundle {
val outer: HasTileLinkMasterPort val outer: HasTileLinkMasterPort
val master = outer.masterNode.bundleOut val master = outer.masterNode.bundleOut
val interrupts = outer.intNode.bundleIn
} }
trait HasTileLinkMasterPortModule { trait HasTileLinkMasterPortModule {
@ -73,7 +75,6 @@ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends
class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
with HasTileLinkMasterPortBundle { with HasTileLinkMasterPortBundle {
val hartid = UInt(INPUT, p(XLen)) val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts()(p).asInput
val resetVector = UInt(INPUT, p(XLen)) val resetVector = UInt(INPUT, p(XLen))
} }

View File

@ -53,9 +53,8 @@ object PLICConsts
} }
/** Platform-Level Interrupt Controller */ /** Platform-Level Interrupt Controller */
class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC000000)(implicit p: Parameters) extends LazyModule class TLPLIC(maxPriorities: Int, address: BigInt = 0xC000000)(implicit p: Parameters) extends LazyModule
{ {
val contextsPerHart = if (supervisor) 2 else 1
require (maxPriorities >= 0) require (maxPriorities >= 0)
// plic0 => max devices 1023 // plic0 => max devices 1023
@ -81,7 +80,7 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
val intnode = IntNexusNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 1024, numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 1024, numSinkPorts = 0 to 1024,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart, Seq(Resource(device, "int"))))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
/* Negotiated sizes */ /* Negotiated sizes */