diff --git a/src/main/scala/coreplex/RocketTiles.scala b/src/main/scala/coreplex/RocketTiles.scala index 5026cda9..d778feef 100644 --- a/src/main/scala/coreplex/RocketTiles.scala +++ b/src/main/scala/coreplex/RocketTiles.scala @@ -8,6 +8,7 @@ import diplomacy._ import rocket._ import tile._ import uncore.tilelink2._ +import util._ sealed trait ClockCrossing case object Synchronous extends ClockCrossing @@ -21,12 +22,17 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { val module: HasRocketTilesModule private val crossing = p(RocketCrossing) - private val configs = p(RocketTilesKey) + val tileParams = p(RocketTilesKey) - // TODO: hack to fix deduplication; see PR https://github.com/ucb-bar/berkeley-hardfloat/pull/14 - hardfloat.consts + // Handle interrupts to be routed directly into each tile + val localIntNodes = tileParams map { t => + (t.core.nLocalInterrupts > 0).option(IntInputNode()) + } - val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) => + // Make a function for each tile that will wire it to coreplex devices and crossbars, + // according to the specified type of clock crossing. + val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex + val rocketWires: Seq[HasRocketTilesBundle => Unit] = wiringTuple.map { case ((lip, c), i) => val pWithExtra = p.alterPartial { case TileKey => c case BuildRoCC => c.rocc @@ -37,10 +43,11 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { val debugNode = IntInternalInputNode(IntSourcePortSimple()) val intBar = LazyModule(new IntXbar) - intBar.intnode := debugNode - intBar.intnode := clint.intnode // msip+mtip - intBar.intnode := plic.intnode // meip + intBar.intnode := debugNode // debug + intBar.intnode := clint.intnode // msip+mtip + intBar.intnode := plic.intnode // meip if (c.core.useVM) intBar.intnode := plic.intnode // seip + lip.foreach { intBar.intnode := _ } // lip crossing match { case Synchronous => { @@ -103,6 +110,7 @@ trait HasRocketTiles extends CoreplexRISCVPlatform { trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle { val outer: HasRocketTiles + val local_interrupts = HeterogeneousBag(outer.localIntNodes.flatten.map(_.bundleIn)) val tcrs = Vec(p(RocketTilesKey).size, new Bundle { val clock = Clock(INPUT) val reset = Bool(INPUT) diff --git a/src/main/scala/rocket/Tile.scala b/src/main/scala/rocket/Tile.scala index 4f386d45..ca710269 100644 --- a/src/main/scala/rocket/Tile.scala +++ b/src/main/scala/rocket/Tile.scala @@ -95,12 +95,9 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p ResourceBinding { 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 => + csrIntMap.lift(i).foreach { j => s.resources.foreach { r => r.bind(device, ResourceInt(j)) } @@ -122,7 +119,8 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne require(outer.p(PAddrBits) >= outer.masterNode.edgesIn(0).bundle.addressBits) val core = Module(p(BuildCore)(outer.p)) - core.io.hartid := io.hartid + decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector + core.io.hartid := io.hartid // Pass through the hartid outer.frontend.module.io.cpu <> core.io.imem outer.frontend.module.io.resetVector := io.resetVector dcachePorts += core.io.dmem // TODO outer.dcachePorts += () => module.core.io.dmem ?? @@ -136,12 +134,6 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne 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 val h = dcachePorts.size diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index d74c8499..ffb2b6f9 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -35,7 +35,7 @@ trait HasTopLevelNetworks extends HasPeripheryParameters { val socBus = LazyModule(new TLXbar) // Wide or unordered-access slave devices (TL-UH) val peripheryBus = LazyModule(new TLXbar) // Narrow and ordered-access slave devices (TL-UL) - val intBus = LazyModule(new IntXbar) // Interrupts + val intBus = LazyModule(new IntXbar) // Device and global external interrupts val fsb = LazyModule(new TLBuffer(BufferParams.none)) // Master devices talking to the frontside of the L2 val bsb = LazyModule(new TLBuffer(BufferParams.none)) // Slave devices talking to the backside of the L2 val mem = Seq.fill(nMemoryChannels) { LazyModule(new TLXbar) } // Ports out to DRAM diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 3b72d40d..bebe2bfb 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -52,13 +52,11 @@ trait HasTileLinkMasterPort extends HasTileParameters { implicit val p: Parameters val module: HasTileLinkMasterPortModule val masterNode = TLOutputNode() - val intNode = IntSinkNode(IntSinkPortSimple()) } trait HasTileLinkMasterPortBundle { val outer: HasTileLinkMasterPort val master = outer.masterNode.bundleOut - val interrupts = outer.intNode.bundleIn } trait HasTileLinkMasterPortModule { @@ -67,15 +65,18 @@ trait HasTileLinkMasterPortModule { } abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile - with HasTileLinkMasterPort { + with HasTileLinkMasterPort + with HasExternalInterrupts { override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this)) } class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) - with HasTileLinkMasterPortBundle { + with HasTileLinkMasterPortBundle + with HasExternalInterruptsBundle { val hartid = UInt(INPUT, p(XLen)) val resetVector = UInt(INPUT, p(XLen)) } class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io) with HasTileLinkMasterPortModule + with HasExternalInterruptsModule diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index 00a00663..1cbac9c8 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -4,13 +4,53 @@ package tile import Chisel._ import config.Parameters +import uncore.tilelink2.{IntSinkNode, IntSinkPortSimple} import util._ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) { - val lip = Vec(coreParams.nLocalInterrupts, Bool()) val debug = Bool() val mtip = Bool() val msip = Bool() val meip = Bool() val seip = usingVM.option(Bool()) + val lip = Vec(coreParams.nLocalInterrupts, Bool()) +} + +// Use diplomatic interrupts to external interrupts from the coreplex into the tile +trait HasExternalInterrupts extends HasTileParameters { + implicit val p: Parameters + val module: HasExternalInterruptsModule + + val intNode = IntSinkNode(IntSinkPortSimple()) + + // TODO: the order of the following two functions must match, and + // also match the order which things are connected to the + // per-tile crossbar in coreplex.HasRocketTiles + + // debug, msip, mtip, meip, seip, lip offsets in CSRs + def csrIntMap: List[Int] = { + val nlips = tileParams.core.nLocalInterrupts + List(65535, 3, 7, 11, 9) ++ List.tabulate(nlips)(_ + 16) + } +} + +trait HasExternalInterruptsBundle { + val outer: HasExternalInterrupts + val interrupts = outer.intNode.bundleIn +} + +trait HasExternalInterruptsModule { + val outer: HasExternalInterrupts + val io: HasExternalInterruptsBundle + + // go from flat diplomatic Interrupts to bundled TileInterrupts + def decodeCoreInterrupts(core: TileInterrupts) { + val core_ips = Vec( + core.debug, + core.msip, + core.mtip, + core.meip, + core.seip.getOrElse(Wire(Bool()))) ++ core.lip + core_ips.zip(io.interrupts(0)).foreach { case(c, i) => c := i } + } }