From 1579ddb97eb6a7ab0f65f92d218cb3c579663de7 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 28 Dec 2017 14:00:13 -0800 Subject: [PATCH] tile: removed RocketTileWrapper. RocketTile now HasCrossing. --- src/main/scala/coreplex/RocketCoreplex.scala | 56 +++++++++++++---- src/main/scala/groundtest/Tile.scala | 4 +- src/main/scala/tile/BaseTile.scala | 10 ++- src/main/scala/tile/Interrupts.scala | 20 ++---- src/main/scala/tile/RocketTile.scala | 65 ++------------------ 5 files changed, 65 insertions(+), 90 deletions(-) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index bcf4541a..a070123b 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -77,27 +77,59 @@ trait HasRocketTiles extends HasTiles } private val crossingTuples = rocketTileParams.zip(crossings) - // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, + // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. + // Note that we also inject new nodes into the tile itself, + // also based on the crossing type. 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( - params = tp, - crossing = crossing.crossingType - )(p.alterPartial { + val rocket = LazyModule(new RocketTile(tp, crossing.crossingType)(p.alterPartial { case TileKey => tp case BuildRoCC => tp.rocc case SharedMemoryTLEdge => sharedMemoryTLEdge - case RocketCrossingKey => List(crossing) }) ).suggestName(tp.name) // Connect the master ports of the tile to the system bus - sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(wrapper.crossTLOut :=* wrapper.masterNode) } + + def tileMasterBuffering: TLOutwardNode = rocket { + // The buffers needed to cut feed-through paths are microarchitecture specific, so belong here + val masterBuffer = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1))) + crossing.crossingType match { + case _: AsynchronousCrossing => rocket.masterNode + case SynchronousCrossing(b) => + require (!tp.boundaryBuffers || (b.depth >= 1 && !b.flow && !b.pipe), "Buffer misconfiguration creates feed-through paths") + rocket.masterNode + case RationalCrossing(dir) => + require (dir != SlowToFast, "Misconfiguration? Core slower than fabric") + if (tp.boundaryBuffers) { + masterBuffer.node :=* rocket.masterNode + } else { + rocket.masterNode + } + } + } + + sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) } // Connect the slave ports of the tile to the periphery bus - pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(wrapper.slaveNode :*= wrapper.crossTLIn) } + + def tileSlaveBuffering: TLInwardNode = rocket { + val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) + crossing.crossingType match { + case _: SynchronousCrossing => rocket.slaveNode // requirement already checked + case _: AsynchronousCrossing => rocket.slaveNode + case _: RationalCrossing => + if (tp.boundaryBuffers) { + DisableMonitors { implicit p => rocket.slaveNode :*= slaveBuffer.node } + } else { + rocket.slaveNode + } + } + } + + pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(tileSlaveBuffering :*= rocket.crossTLIn) } // Handle all the different types of interrupts crossing to or from the tile: // 1. Debug interrupt is definitely asynchronous in all cases. @@ -110,10 +142,10 @@ trait HasRocketTiles extends HasTiles // are decoded from rocket.intNode inside the tile. // 1. always async crossing for debug - wrapper.intInwardNode := wrapper { IntSyncCrossingSink(3) } := debug.intnode + rocket.intInwardNode := rocket { IntSyncCrossingSink(3) } := debug.intnode // 2. clint+plic conditionally crossing - val periphIntNode = wrapper.intInwardNode :=* wrapper.crossIntIn + val periphIntNode = rocket.intInwardNode :=* rocket.crossIntIn periphIntNode := clint.intnode // msip+mtip periphIntNode := plic.intnode // meip if (tp.core.useVM) periphIntNode := plic.intnode // seip @@ -123,10 +155,10 @@ trait HasRocketTiles extends HasTiles // 4. conditional crossing from core to PLIC FlipRendering { implicit p => - plic.intnode :=* wrapper.crossIntOut :=* wrapper.intOutwardNode + plic.intnode :=* rocket.crossIntOut :=* rocket.intOutwardNode } - wrapper + rocket } } diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 56176d4b..904cd0cb 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -30,7 +30,9 @@ trait GroundTestTileParams extends TileParams { case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]] -abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) { +abstract class GroundTestTile(params: GroundTestTileParams) + (implicit p: Parameters) + extends BaseTile(params, crossing = SynchronousCrossing())(p) { val intInwardNode: IntInwardNode = IntIdentityNode() val intOutwardNode: IntOutwardNode = IntIdentityNode() val slaveNode: TLInwardNode = TLIdentityNode() diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 7b2e37b0..eae2b993 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -5,7 +5,7 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex.{CacheBlockBytes, SystemBusKey} +import freechips.rocketchip.coreplex._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.rocket._ @@ -144,8 +144,11 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters { } /** Base class for all Tiles that use TileLink */ -abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile - with HasTileParameters { +abstract class BaseTile( + tileParams: TileParams, + val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends BareTile + with HasTileParameters + with HasCrossing { def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]] def masterNode: TLOutwardNode def slaveNode: TLInwardNode @@ -156,6 +159,7 @@ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends protected val tlMasterXbar = LazyModule(new TLXbar) protected val tlSlaveXbar = LazyModule(new TLXbar) protected val intXbar = LazyModule(new IntXbar) + protected val intSinkNode = IntSinkNode(IntSinkPortSimple()) def connectTLSlave(node: TLNode, bytes: Int) { DisableMonitors { implicit p => diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index af115ce1..13c5d64e 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -19,11 +19,10 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) { } // Use diplomatic interrupts to external interrupts from the coreplex into the tile -trait HasExternalInterrupts extends HasTileParameters { - implicit val p: Parameters - val module: HasExternalInterruptsModule +trait HasExternalInterrupts { this: BaseTile => - val intInwardNode = IntSinkNode(IntSinkPortSimple()) + val intInwardNode = intXbar.intnode + intSinkNode := intXbar.intnode val intcDevice = new Device { def describe(resources: ResourceBindings): Description = { @@ -37,7 +36,7 @@ trait HasExternalInterrupts extends HasTileParameters { ResourceBinding { Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartId))) - intInwardNode.edges.in.flatMap(_.source.sources).map { case s => + intSinkNode.edges.in.flatMap(_.source.sources).map { case s => for (i <- s.range.start until s.range.end) { csrIntMap.lift(i).foreach { j => s.resources.foreach { r => @@ -59,15 +58,6 @@ trait HasExternalInterrupts extends HasTileParameters { List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16) } -} - -trait HasExternalInterruptsBundle { - val outer: HasExternalInterrupts -} - -trait HasExternalInterruptsModule { - val outer: HasExternalInterrupts - // go from flat diplomatic Interrupts to bundled TileInterrupts def decodeCoreInterrupts(core: TileInterrupts) { val async_ips = Seq(core.debug) @@ -80,7 +70,7 @@ trait HasExternalInterruptsModule { val core_ips = core.lip - val (interrupts, _) = outer.intInwardNode.in(0) + val (interrupts, _) = intSinkNode.in(0) (async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i } } } diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 5fd62523..91ff4aa8 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -5,11 +5,9 @@ package freechips.rocketchip.tile import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ +import freechips.rocketchip.coreplex.CoreplexClockCrossing import freechips.rocketchip.diplomacy._ import freechips.rocketchip.rocket._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ case class RocketTileParams( @@ -30,7 +28,10 @@ case class RocketTileParams( require(dcache.isDefined) } -class RocketTile(val rocketParams: RocketTileParams)(implicit p: Parameters) extends BaseTile(rocketParams)(p) +class RocketTile( + val rocketParams: RocketTileParams, + crossing: CoreplexClockCrossing) + (implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p) with HasExternalInterrupts with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend @@ -61,14 +62,13 @@ class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer) } class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer)) - with HasExternalInterruptsModule with HasLazyRoCCModule with CanHaveScratchpadModule { val core = Module(p(BuildCore)(outer.p)) val uncorrectable = RegInit(Bool(false)) - decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector + outer.decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector outer.busErrorUnit.foreach { beu => core.io.interrupts.buserror.get := beu.module.io.interrupt } core.io.hartid := io.hartid // Pass through the hartid io.trace.foreach { _ := core.io.trace } @@ -103,56 +103,3 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne dcacheArb.io.requestor <> dcachePorts ptw.io.requestor <> ptwPorts } - -class RocketTileWrapperBundle[+L <: RocketTileWrapper](_outer: L) extends BaseTileBundle(_outer) - with CanHaltAndCatchFire { - val halt_and_catch_fire = _outer.rocket.module.io.halt_and_catch_fire.map(_.cloneType) -} - -class RocketTileWrapper( - params: RocketTileParams, - val crossing: CoreplexClockCrossing) - (implicit p: Parameters) extends BaseTile(params) with HasCrossing { - - val rocket = LazyModule(new RocketTile(params)) - - // The buffers needed to cut feed-through paths are microarchitecture specific, so belong here - val masterBuffer = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1))) - val masterNode = crossing match { - case _: AsynchronousCrossing => rocket.masterNode - case SynchronousCrossing(b) => - require (!params.boundaryBuffers || (b.depth >= 1 && !b.flow && !b.pipe), "Buffer misconfiguration creates feed-through paths") - rocket.masterNode - case RationalCrossing(dir) => - require (dir != SlowToFast, "Misconfiguration? Core slower than fabric") - if (params.boundaryBuffers) { - masterBuffer.node :=* rocket.masterNode - } else { - rocket.masterNode - } - } - - val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) - val slaveNode: TLInwardNode = crossing match { - case _: SynchronousCrossing => rocket.slaveNode // requirement already checked - case _: AsynchronousCrossing => rocket.slaveNode - case _: RationalCrossing => - if (params.boundaryBuffers) { - DisableMonitors { implicit p => rocket.slaveNode :*= slaveBuffer.node } - } else { - rocket.slaveNode - } - } - - rocket.intInwardNode := intXbar.intnode - val intInwardNode = intXbar.intnode - val intOutwardNode = rocket.intOutwardNode - - override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) { - // signals that do not change based on crossing type: - rocket.module.io.hartid := io.hartid - rocket.module.io.reset_vector := io.reset_vector - io.trace.foreach { _ := rocket.module.io.trace.get } - io.halt_and_catch_fire.foreach { _ := rocket.module.io.halt_and_catch_fire.get } - } -}