From 03f2fe02ace1fb538f1883d78da48c9858bdaac4 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 27 Jan 2017 17:09:43 -0800 Subject: [PATCH] coreplex: support rational crossing to L2 (#534) --- src/main/scala/coreplex/Configs.scala | 13 ++ src/main/scala/coreplex/Coreplex.scala | 25 +--- src/main/scala/coreplex/RocketTiles.scala | 129 +++++++++--------- src/main/scala/rocket/Tile.scala | 24 ++++ .../scala/rocketchip/RocketPlexMaster.scala | 7 + 5 files changed, 112 insertions(+), 86 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 0c94b128..6a5ed0fe 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -18,6 +18,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { case PAddrBits => 32 case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ case ASIdBits => 7 + case RocketCrossing => Synchronous //Params used by all caches case CacheName("L1I") => CacheConfig( nSets = 64, @@ -215,3 +216,15 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => { class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => { case BootROMFile => bootROMFile }) + +class WithSynchronousRocketTiles extends Config((site, here, up) => { + case RocketCrossing => Synchronous +}) + +class WithAynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => { + case RocketCrossing => Asynchronous(depth, sync) +}) + +class WithRationalRocketTiles extends Config((site, here, up) => { + case RocketCrossing => Rational +}) diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 8e7fcbe2..1390fc4d 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -12,35 +12,16 @@ import util._ class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex with CoreplexRISCVPlatform with HasL2MasterPort - with HasSynchronousRocketTiles { + with HasRocketTiles { override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) } class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) with CoreplexRISCVPlatformBundle with HasL2MasterPortBundle - with HasSynchronousRocketTilesBundle + with HasRocketTilesBundle class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) with CoreplexRISCVPlatformModule with HasL2MasterPortModule - with HasSynchronousRocketTilesModule - -///// - -class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex - with CoreplexRISCVPlatform - with HasL2MasterPort - with HasAsynchronousRocketTiles { - override lazy val module = new MultiClockCoreplexModule(this, () => new MultiClockCoreplexBundle(this)) -} - -class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) - with CoreplexRISCVPlatformBundle - with HasL2MasterPortBundle - with HasAsynchronousRocketTilesBundle - -class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) - with CoreplexRISCVPlatformModule - with HasL2MasterPortModule - with HasAsynchronousRocketTilesModule + with HasRocketTilesModule diff --git a/src/main/scala/coreplex/RocketTiles.scala b/src/main/scala/coreplex/RocketTiles.scala index 6b3ab457..ad81ad2a 100644 --- a/src/main/scala/coreplex/RocketTiles.scala +++ b/src/main/scala/coreplex/RocketTiles.scala @@ -8,84 +8,85 @@ import diplomacy._ import rocket._ import uncore.tilelink2._ +sealed trait ClockCrossing +case object Synchronous extends ClockCrossing +case object Rational extends ClockCrossing +case class Asynchronous(depth: Int, sync: Int = 2) extends ClockCrossing + case object RocketConfigs extends Field[Seq[RocketConfig]] +case object RocketCrossing extends Field[ClockCrossing] -trait HasSynchronousRocketTiles extends CoreplexRISCVPlatform { - val module: HasSynchronousRocketTilesModule +trait HasRocketTiles extends CoreplexRISCVPlatform { + val module: HasRocketTilesModule - val rocketTiles: Seq[RocketTile] = p(RocketConfigs).map { c => - LazyModule(new RocketTile(c)(p.alterPartial { - case SharedMemoryTLEdge => l1tol2.node.edgesIn(0) - case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits - }))} - - rocketTiles.foreach { r => - r.masterNodes.foreach { l1tol2.node := TLBuffer()(_) } - r.slaveNode.foreach { _ := cbus.node } + private val crossing = p(RocketCrossing) + private val configs = p(RocketConfigs) + private val pWithExtra = p.alterPartial { + case SharedMemoryTLEdge => l1tol2.node.edgesIn(0) + case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits } - val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() } + private val rocketTileIntNodes = configs.map { _ => IntInternalOutputNode() } rocketTileIntNodes.foreach { _ := plic.intnode } -} -trait HasSynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle { - val outer: HasSynchronousRocketTiles -} + private def wireInterrupts(x: TileInterrupts, i: Int) { + x := clint.module.io.tiles(i) + x.debug := debug.module.io.debugInterrupts(i) + x.meip := rocketTileIntNodes(i).bundleOut(0)(0) + x.seip.foreach { _ := rocketTileIntNodes(i).bundleOut(0)(1) } + } -trait HasSynchronousRocketTilesModule extends CoreplexRISCVPlatformModule { - val outer: HasSynchronousRocketTiles - val io: HasSynchronousRocketTilesBundle - - outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) => - tile.io.hartid := UInt(i) - tile.io.resetVector := io.resetVector - tile.io.interrupts := outer.clint.module.io.tiles(i) - tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - tile.io.interrupts.meip := outer.rocketTileIntNodes(i).bundleOut(0)(0) - tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1)) + val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) => + crossing match { + case Synchronous => { + val tile = LazyModule(new RocketTile(c)(pWithExtra)) + tile.masterNodes.foreach { l1tol2.node := TLBuffer()(_) } + tile.slaveNode.foreach { _ := cbus.node } + (io: HasRocketTilesBundle) => { + // leave clock as default (simpler for hierarchical PnR) + tile.module.io.hartid := UInt(i) + tile.module.io.resetVector := io.resetVector + wireInterrupts(tile.module.io.interrupts, i) + } + } + case Asynchronous(depth, sync) => { + val wrapper = LazyModule(new AsyncRocketTile(c)(pWithExtra)) + wrapper.masterNodes.foreach { l1tol2.node := TLAsyncCrossingSink(depth, sync)(_) } + wrapper.slaveNode.foreach { _ := TLAsyncCrossingSource(sync)(cbus.node) } + (io: HasRocketTilesBundle) => { + wrapper.module.clock := io.tcrs(i).clock + wrapper.module.reset := io.tcrs(i).reset + wrapper.module.io.hartid := UInt(i) + wrapper.module.io.resetVector := io.resetVector + wireInterrupts(wrapper.module.io.interrupts, i) + } + } + case Rational => { + val wrapper = LazyModule(new RationalRocketTile(c)(pWithExtra)) + wrapper.masterNodes.foreach { l1tol2.node := TLRationalCrossingSink()(_) } + wrapper.slaveNode.foreach { _ := TLRationalCrossingSource()(cbus.node) } + (io: HasRocketTilesBundle) => { + wrapper.module.clock := io.tcrs(i).clock + wrapper.module.reset := io.tcrs(i).reset + wrapper.module.io.hartid := UInt(i) + wrapper.module.io.resetVector := io.resetVector + wireInterrupts(wrapper.module.io.interrupts, i) + } + } + } } } -trait HasAsynchronousRocketTiles extends CoreplexRISCVPlatform { - val module: HasAsynchronousRocketTilesModule - - import rocket.AsyncRocketTile - val rocketTiles: Seq[AsyncRocketTile] = p(RocketConfigs).map { c => - LazyModule(new AsyncRocketTile(c)(p.alterPartial { - case SharedMemoryTLEdge => l1tol2.node.edgesIn(0) - case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits - }))} - - rocketTiles.foreach { r => - r.masterNodes.foreach { l1tol2.node := TLAsyncCrossingSink()(_) } - r.slaveNode.foreach { _ := TLAsyncCrossingSource()(cbus.node) } - } - - val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() } - rocketTileIntNodes.foreach { _ := plic.intnode } -} - -trait HasAsynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle { - val outer: HasAsynchronousRocketTiles - - val tcrs = Vec(nTiles, new Bundle { +trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle { + val outer: HasRocketTiles + val tcrs = Vec(p(RocketConfigs).size, new Bundle { val clock = Clock(INPUT) val reset = Bool(INPUT) }) } -trait HasAsynchronousRocketTilesModule extends CoreplexRISCVPlatformModule { - val outer: HasAsynchronousRocketTiles - val io: HasAsynchronousRocketTilesBundle - - outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) => - tile.clock := io.tcrs(i).clock - tile.reset := io.tcrs(i).reset - tile.io.hartid := UInt(i) - tile.io.resetVector := io.resetVector - tile.io.interrupts := outer.clint.module.io.tiles(i) - tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - tile.io.interrupts.meip := outer.rocketTileIntNodes(i).bundleOut(0)(0) - tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1)) - } +trait HasRocketTilesModule extends CoreplexRISCVPlatformModule { + val outer: HasRocketTiles + val io: HasRocketTilesBundle + outer.rocketWires.foreach { _(io) } } diff --git a/src/main/scala/rocket/Tile.scala b/src/main/scala/rocket/Tile.scala index abfecce8..5efba72f 100644 --- a/src/main/scala/rocket/Tile.scala +++ b/src/main/scala/rocket/Tile.scala @@ -73,3 +73,27 @@ class AsyncRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModul rocket.module.io.resetVector := io.resetVector } } + +class RationalRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModule { + val rocket = LazyModule(new RocketTile(c)) + + val masterNodes = rocket.masterNodes.map(_ => TLRationalOutputNode()) + val slaveNode = rocket.slaveNode.map(_ => TLRationalInputNode()) + + (rocket.masterNodes zip masterNodes) foreach { case (r,n) => n := TLRationalCrossingSource()(r) } + (rocket.slaveNode zip slaveNode) foreach { case (r,n) => r := TLRationalCrossingSink()(n) } + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val master = masterNodes.head.bundleOut // TODO fix after Chisel #366 + val slave = slaveNode.map(_.bundleIn) + val hartid = UInt(INPUT, p(XLen)) + val interrupts = new TileInterrupts()(p).asInput + val resetVector = UInt(INPUT, p(XLen)) + } + rocket.module.io.interrupts := ShiftRegister(io.interrupts, 1) + // signals that do not change: + rocket.module.io.hartid := io.hartid + rocket.module.io.resetVector := io.resetVector + } +} diff --git a/src/main/scala/rocketchip/RocketPlexMaster.scala b/src/main/scala/rocketchip/RocketPlexMaster.scala index ff6f7652..3ea1e880 100644 --- a/src/main/scala/rocketchip/RocketPlexMaster.scala +++ b/src/main/scala/rocketchip/RocketPlexMaster.scala @@ -29,4 +29,11 @@ trait RocketPlexMasterBundle extends L2CrossbarBundle { trait RocketPlexMasterModule extends L2CrossbarModule { val outer: RocketPlexMaster val io: RocketPlexMasterBundle + val clock: Clock + val reset: Bool + + outer.coreplex.module.io.tcrs.foreach { case tcr => + tcr.clock := clock + tcr.reset := reset + } }