From ddaeedf2d07093eb9d52dc26603c44d4d0f59e1f Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 13 Dec 2017 19:00:29 -0800 Subject: [PATCH] coreplex: make HasTiles more generic HasTiles now deals with only extremely general tile IOs. Some RocketTiles specific behavior moved into RocketCoreplex. BaseTile now has optional LocalInterruptNode. --- src/main/scala/coreplex/BaseCoreplex.scala | 62 -------------------- src/main/scala/coreplex/HasTiles.scala | 52 ++++++++++++++++ src/main/scala/coreplex/RocketCoreplex.scala | 31 ++++++---- src/main/scala/groundtest/Tile.scala | 1 + src/main/scala/tile/BaseTile.scala | 2 + src/main/scala/tile/Interrupts.scala | 3 +- src/main/scala/tile/RocketTile.scala | 1 + 7 files changed, 79 insertions(+), 73 deletions(-) create mode 100644 src/main/scala/coreplex/HasTiles.scala diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index bba04d0d..be23ee83 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -5,11 +5,8 @@ package freechips.rocketchip.coreplex import Chisel._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.interrupts._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.tilelink._ -import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants} -import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} import freechips.rocketchip.util._ /** BareCoreplex is the root class for creating a coreplex sub-system */ @@ -27,25 +24,6 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod println(outer.dts) } -trait HasTiles extends HasSystemBus { - protected def tileParams: Seq[TileParams] - def nRocketTiles = tileParams.size - def hartIdList = tileParams.map(_.hartid) - - // Handle interrupts to be routed directly into each tile - // TODO: figure out how to merge the localIntNodes and coreIntXbar - def localIntCounts = tileParams.map(_.core.nLocalInterrupts) - lazy val localIntNodes = tileParams.zipWithIndex map { case (t, i) => { - (t.core.nLocalInterrupts > 0).option({ - val n = LazyModule(new IntXbar) - n.suggestName(s"localIntXbar_${i}") - n.intnode}) - } - } - - val tiles: Seq[BaseTile] -} - /** Base Coreplex class with no peripheral devices or ports added */ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with HasInterruptBus @@ -80,46 +58,6 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex } } -class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle - with HasExternallyDrivenTileConstants - with Clocked - -trait HasTilesBundle { - val tile_inputs: Vec[ClockedTileInputs] -} - -trait HasTilesModuleImp extends LazyModuleImp - with HasTilesBundle - with HasResetVectorWire { - val outer: HasTiles - - def resetVectorBits: Int = { - // Consider using the minimum over all widths, rather than enforcing homogeneity - val vectors = outer.tiles.map(_.module.io.reset_vector) - require(vectors.tail.forall(_.getWidth == vectors.head.getWidth)) - vectors.head.getWidth - } - val tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedTileInputs()(p.alterPartial { - case SharedMemoryTLEdge => outer.sharedMemoryTLEdge - }))) - - // Unconditionally wire up the non-diplomatic tile inputs - outer.tiles.map(_.module).zip(tile_inputs).foreach { case(tile, wire) => - tile.clock := wire.clock - tile.reset := wire.reset - tile.io.hartid := wire.hartid - tile.io.reset_vector := wire.reset_vector - } - - // Default values for tile inputs; may be overriden in other traits - tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) => - wire.clock := clock - wire.reset := reset - wire.hartid := UInt(i) - wire.reset_vector := global_reset_vector - } -} - abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) { println("Generated Address Map") private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1 diff --git a/src/main/scala/coreplex/HasTiles.scala b/src/main/scala/coreplex/HasTiles.scala new file mode 100644 index 00000000..8c6b3612 --- /dev/null +++ b/src/main/scala/coreplex/HasTiles.scala @@ -0,0 +1,52 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants} +import freechips.rocketchip.util._ + +class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle + with HasExternallyDrivenTileConstants + with Clocked + +trait HasTiles extends HasSystemBus { + val tiles: Seq[BaseTile] + protected def tileParams: Seq[TileParams] + def nTiles: Int = tileParams.size + def hartIdList: Seq[Int] = tileParams.map(_.hartid) + def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts) +} + +trait HasTilesBundle { + val tile_inputs: Vec[ClockedTileInputs] +} + +trait HasTilesModuleImp extends LazyModuleImp + with HasTilesBundle + with HasResetVectorWire { + val outer: HasTiles + + def resetVectorBits: Int = { + // Consider using the minimum over all widths, rather than enforcing homogeneity + val vectors = outer.tiles.map(_.module.io.reset_vector) + require(vectors.tail.forall(_.getWidth == vectors.head.getWidth)) + vectors.head.getWidth + } + + val tile_inputs = Wire(Vec(outer.nTiles, new ClockedTileInputs()(p.alterPartial { + case SharedMemoryTLEdge => outer.sharedMemoryTLEdge + }))) + + // Unconditionally wire up the non-diplomatic tile inputs + outer.tiles.map(_.module).zip(tile_inputs).foreach { case(tile, wire) => + tile.clock := wire.clock + tile.reset := wire.reset + tile.io.hartid := wire.hartid + tile.io.reset_vector := wire.reset_vector + } +} + diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 2860a9fd..e2b9ce00 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -67,19 +67,19 @@ trait HasRocketTiles extends HasTiles with HasPeripheryDebug { val module: HasRocketTilesModuleImp - protected val tileParams = p(RocketTilesKey) - private val NumRocketTiles = tileParams.size + protected val rocketTileParams = p(RocketTilesKey) + private val NumRocketTiles = rocketTileParams.size private val crossingParams = p(RocketCrossingKey) private val crossings = crossingParams.size match { case 1 => List.fill(NumRocketTiles) { crossingParams.head } case NumRocketTiles => crossingParams case _ => throw new Exception("RocketCrossingKey.size must == 1 or == RocketTilesKey.size") } - private val crossingTuples = localIntNodes.zip(tileParams).zip(crossings) + private val crossingTuples = rocketTileParams.zip(crossings) // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, // according to the specified type of clock crossing. - val tiles: Seq[BaseTile] = crossingTuples.map { case ((lip, tp), crossing) => + val rocketTiles = crossingTuples.map { case (tp, crossing) => // For legacy reasons, it is convenient to store some state // in the global Parameters about the specific tile being built now val wrapper = LazyModule(new RocketTileWrapper( @@ -109,18 +109,20 @@ trait HasRocketTiles extends HasTiles // NOTE: The order of calls to := matters! They must match how interrupts // are decoded from rocket.intNode inside the tile. - wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode // 1. always async crossign + // 1. always async crossing for debug + wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode - // 2. clint+plic conditionak crossing + // 2. clint+plic conditionally crossing val periphIntNode = wrapper.intXbar.intnode :=* wrapper.crossIntIn periphIntNode := clint.intnode // msip+mtip periphIntNode := plic.intnode // meip if (tp.core.useVM) periphIntNode := plic.intnode // seip - lip.foreach { wrapper.intXbar.intnode := _ } // 3. lip never crosses + // 3. local interrupts never cross + // this.localIntNode is wired up externally // lip - // From core to PLIC - wrapper.rocket.intOutputNode.foreach { i => // 4. conditional crossing + // 4. conditional crossing from core to PLIC + wrapper.rocket.intOutputNode.foreach { i => FlipRendering { implicit p => plic.intnode :=* wrapper.crossIntOut :=* i } @@ -137,8 +139,17 @@ trait HasRocketTilesModuleImp extends HasTilesModuleImp class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex with HasRocketTiles { + val tiles = rocketTiles + def tileParams = rocketTiles.map(_.tileParams) override lazy val module = new RocketCoreplexModule(this) } class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer) - with HasRocketTilesModuleImp + with HasRocketTilesModuleImp { + tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) => + wire.clock := clock + wire.reset := reset + wire.hartid := UInt(i) + wire.reset_vector := global_reset_vector + } +} diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index ccb8b853..766d5e81 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -30,6 +30,7 @@ case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]] abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) { val slave = None + val localIntNode = None val dcacheOpt = params.dcache.map { dc => LazyModule(new DCache(0)) } override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this)) diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index dfa84a58..6e6bbb18 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -6,6 +6,7 @@ import Chisel._ import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ import freechips.rocketchip.rocket._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ @@ -111,6 +112,7 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters { abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile with HasTileParameters { def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]] + val localIntNode: Option[IntInwardNode] } abstract class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index 0043089d..368d1add 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple} +import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) { @@ -23,6 +23,7 @@ trait HasExternalInterrupts extends HasTileParameters { val module: HasExternalInterruptsModule val intNode = IntSinkNode(IntSinkPortSimple()) + val localIntNode: Option[IntInwardNode] = None // TODO: the order of the following two functions must match, and // also match the order which things are connected to the diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 432fc3af..cb7f800f 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -230,6 +230,7 @@ class RocketTileWrapper( } val intXbar = LazyModule(new IntXbar) + val localIntNode = Some(intXbar.intnode) rocket.intNode := intXbar.intnode override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) {