diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 9dbf0080..e02b0190 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -23,7 +23,7 @@ case object BankIdLSB extends Field[Int] /** Function for building some kind of coherence manager agent */ case object BuildL2CoherenceManager extends Field[(Int, Parameters) => CoherenceAgent] /** Function for building some kind of tile connected to a reset signal */ -case object BuildTiles extends Field[Seq[(Bool, Parameters) => Tile]] +case object BuildTiles extends Field[Seq[Parameters => LazyTile]] /** The file to read the BootROM contents from */ case object BootROMFile extends Field[String] @@ -49,6 +49,7 @@ case class CoreplexConfig( } abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { + val lazyTiles = p(BuildTiles) map { _(p) } val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) val debug = LazyModule(new TLDebugModule()) @@ -89,7 +90,7 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( val io: B = b // Build a set of Tiles - val tiles = p(BuildTiles) map { _(reset, p) } + val tiles = outer.lazyTiles.map(_.module) val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } val nCachedPorts = tiles.map(tile => tile.io.cached.size).reduce(_ + _) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 4fea63f1..baff8e7b 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -4,6 +4,7 @@ package coreplex import Chisel._ import junctions._ +import diplomacy._ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ @@ -69,8 +70,8 @@ class BaseCoreplexConfig extends Config ( case NUncachedTileLinkPorts => 1 //Tile Constants case BuildTiles => { - List.tabulate(site(NTiles)){ i => (r: Bool, p: Parameters) => - Module(new RocketTile(resetSignal = r)(p.alterPartial({ + List.tabulate(site(NTiles)){ i => (p: Parameters) => + LazyModule(new RocketTile()(p.alterPartial({ case TileId => i case TLId => "L1toL2" case NUncachedTileLinkPorts => 1 + site(RoccNMemChannels) diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 1e4fc37a..4af784ee 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -9,7 +9,7 @@ import util._ import rocket._ trait DirectConnection { - val tiles: Seq[Tile] + val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] val tlBuffering = TileLinkDepths(1,1,2,2,0) @@ -49,7 +49,7 @@ trait TileClockResetBundle { trait AsyncConnection { val io: TileClockResetBundle - val tiles: Seq[Tile] + val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] (tiles, uncoreTileIOs, io.tcrs).zipped foreach { case (tile, uncore, tcr) => diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 61dee763..bf986429 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -95,8 +95,8 @@ class WithGroundTest extends Config( case BuildTiles => { (0 until site(NTiles)).map { i => val tileSettings = site(GroundTestKey)(i) - (r: Bool, p: Parameters) => { - Module(new GroundTestTile(resetSignal = r)(p.alterPartial({ + (p: Parameters) => { + LazyModule(new GroundTestTile()(p.alterPartial({ case TLId => "L1toL2" case TileId => i case NCachedTileLinkPorts => if(tileSettings.cached > 0) 1 else 0 diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 5a550fb3..63ac1f64 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -96,48 +96,46 @@ abstract class GroundTest(implicit val p: Parameters) extends Module val io = new GroundTestIO } -class GroundTestTile(resetSignal: Bool) - (implicit val p: Parameters) - extends Tile(resetSignal = resetSignal)(p) - with HasGroundTestParameters { - - override val io = new TileIO(bc) { - val success = Bool(OUTPUT) - } - - val test = p(BuildGroundTest)(dcacheParams) - - val ptwPorts = ListBuffer.empty ++= test.io.ptw - val memPorts = ListBuffer.empty ++= test.io.mem - - if (nCached > 0) { - val dcache_io = HellaCache(p(DCacheKey))(dcacheParams) - val dcacheArb = Module(new HellaCacheArbiter(nCached)(dcacheParams)) - - dcacheArb.io.requestor.zip(test.io.cache).foreach { - case (requestor, cache) => - val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams)) - dcacheIF.io.requestor <> cache - requestor <> dcacheIF.io.cache +class GroundTestTile(implicit val p: Parameters) extends LazyTile with HasGroundTestParameters { + lazy val module = new TileImp(this) { + val io = new TileIO(bc) { + val success = Bool(OUTPUT) } - dcache_io.cpu <> dcacheArb.io.mem - io.cached.head <> dcache_io.mem - // SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false - dcache_io.cpu.invalidate_lr := Bool(false) + val test = p(BuildGroundTest)(dcacheParams) - ptwPorts += dcache_io.ptw + val ptwPorts = ListBuffer.empty ++= test.io.ptw + val memPorts = ListBuffer.empty ++= test.io.mem + + if (nCached > 0) { + val dcache_io = HellaCache(p(DCacheKey))(dcacheParams) + val dcacheArb = Module(new HellaCacheArbiter(nCached)(dcacheParams)) + + dcacheArb.io.requestor.zip(test.io.cache).foreach { + case (requestor, cache) => + val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams)) + dcacheIF.io.requestor <> cache + requestor <> dcacheIF.io.cache + } + dcache_io.cpu <> dcacheArb.io.mem + io.cached.head <> dcache_io.mem + + // SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false + dcache_io.cpu.invalidate_lr := Bool(false) + + ptwPorts += dcache_io.ptw + } + + if (ptwPorts.size > 0) { + val ptw = Module(new DummyPTW(ptwPorts.size)) + ptw.io.requestors <> ptwPorts + } + + require(memPorts.size == io.uncached.size) + if (memPorts.size > 0) { + io.uncached <> memPorts + } + + io.success := test.io.status.finished } - - if (ptwPorts.size > 0) { - val ptw = Module(new DummyPTW(ptwPorts.size)) - ptw.io.requestors <> ptwPorts - } - - require(memPorts.size == io.uncached.size) - if (memPorts.size > 0) { - io.uncached <> memPorts - } - - io.success := test.io.status.finished } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 39dd5a35..5d30c1a1 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -3,7 +3,9 @@ package rocket import Chisel._ +import diplomacy._ import uncore.tilelink._ +import uncore.tilelink2._ import uncore.agents._ import uncore.converters._ import uncore.devices._ @@ -39,8 +41,7 @@ class TileIO(c: TileBundleConfig)(implicit p: Parameters) extends Bundle { override def cloneType = new TileIO(c).asInstanceOf[this.type] } -abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null) - (implicit p: Parameters) extends Module(Option(clockSignal), Option(resetSignal)) { +abstract class TileImp(l: LazyTile)(implicit p: Parameters) extends LazyModuleImp(l) { val nCachedTileLinkPorts = p(NCachedTileLinkPorts) val nUncachedTileLinkPorts = p(NUncachedTileLinkPorts) val dcacheParams = p.alterPartial({ case CacheName => "L1D" }) @@ -50,111 +51,117 @@ abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null) xLen = p(XLen), hasSlavePort = p(DataScratchpadSize) > 0) - val io = new TileIO(bc) + val io: TileIO } -class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null) - (implicit p: Parameters) extends Tile(clockSignal, resetSignal)(p) { - val buildRocc = p(BuildRoCC) - val usingRocc = !buildRocc.isEmpty - val nRocc = buildRocc.size - val nFPUPorts = buildRocc.filter(_.useFPU).size +abstract class LazyTile(implicit p: Parameters) extends LazyModule { + val module: TileImp +} - val core = Module(new Rocket) - val icache = Module(new Frontend()(p.alterPartial({ case CacheName => "L1I" }))) - val dcache = HellaCache(p(DCacheKey))(dcacheParams) +class RocketTile(implicit p: Parameters) extends LazyTile { + lazy val module = new TileImp(this) { + val io = new TileIO(bc) + val buildRocc = p(BuildRoCC) + val usingRocc = !buildRocc.isEmpty + val nRocc = buildRocc.size + val nFPUPorts = buildRocc.filter(_.useFPU).size - val ptwPorts = collection.mutable.ArrayBuffer(icache.io.ptw, dcache.ptw) - val dcPorts = collection.mutable.ArrayBuffer(core.io.dmem) - val uncachedArbPorts = collection.mutable.ArrayBuffer(icache.io.mem) - val uncachedPorts = collection.mutable.ArrayBuffer[ClientUncachedTileLinkIO]() - val cachedPorts = collection.mutable.ArrayBuffer(dcache.mem) - core.io.interrupts := io.interrupts - core.io.hartid := io.hartid - icache.io.cpu <> core.io.imem - icache.io.resetVector := io.resetVector + val core = Module(new Rocket) + val icache = Module(new Frontend()(p.alterPartial({ case CacheName => "L1I" }))) + val dcache = HellaCache(p(DCacheKey))(dcacheParams) - val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg))) - fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) + val ptwPorts = collection.mutable.ArrayBuffer(icache.io.ptw, dcache.ptw) + val dcPorts = collection.mutable.ArrayBuffer(core.io.dmem) + val uncachedArbPorts = collection.mutable.ArrayBuffer(icache.io.mem) + val uncachedPorts = collection.mutable.ArrayBuffer[ClientUncachedTileLinkIO]() + val cachedPorts = collection.mutable.ArrayBuffer(dcache.mem) + core.io.interrupts := io.interrupts + core.io.hartid := io.hartid + icache.io.cpu <> core.io.imem + icache.io.resetVector := io.resetVector - if (usingRocc) { - val respArb = Module(new RRArbiter(new RoCCResponse, nRocc)) - core.io.rocc.resp <> respArb.io.out + val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg))) + fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) - val roccOpcodes = buildRocc.map(_.opcodes) - val cmdRouter = Module(new RoccCommandRouter(roccOpcodes)) - cmdRouter.io.in <> core.io.rocc.cmd + if (usingRocc) { + val respArb = Module(new RRArbiter(new RoCCResponse, nRocc)) + core.io.rocc.resp <> respArb.io.out - val roccs = buildRocc.zipWithIndex.map { case (accelParams, i) => - val rocc = accelParams.generator(p.alterPartial({ - case RoccNMemChannels => accelParams.nMemChannels - case RoccNPTWPorts => accelParams.nPTWPorts - })) - val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) - rocc.io.cmd <> cmdRouter.io.out(i) - rocc.io.exception := core.io.rocc.exception - dcIF.io.requestor <> rocc.io.mem - dcPorts += dcIF.io.cache - uncachedArbPorts += rocc.io.autl - rocc + val roccOpcodes = buildRocc.map(_.opcodes) + val cmdRouter = Module(new RoccCommandRouter(roccOpcodes)) + cmdRouter.io.in <> core.io.rocc.cmd + + val roccs = buildRocc.zipWithIndex.map { case (accelParams, i) => + val rocc = accelParams.generator(p.alterPartial({ + case RoccNMemChannels => accelParams.nMemChannels + case RoccNPTWPorts => accelParams.nPTWPorts + })) + val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) + rocc.io.cmd <> cmdRouter.io.out(i) + rocc.io.exception := core.io.rocc.exception + dcIF.io.requestor <> rocc.io.mem + dcPorts += dcIF.io.cache + uncachedArbPorts += rocc.io.autl + rocc + } + + if (nFPUPorts > 0) { + fpuOpt.foreach { fpu => + val fpArb = Module(new InOrderArbiter(new FPInput, new FPResult, nFPUPorts)) + val fp_roccs = roccs.zip(buildRocc) + .filter { case (_, params) => params.useFPU } + .map { case (rocc, _) => rocc.io } + fpArb.io.in_req <> fp_roccs.map(_.fpu_req) + fp_roccs.zip(fpArb.io.in_resp).foreach { + case (rocc, fpu_resp) => rocc.fpu_resp <> fpu_resp + } + fpu.io.cp_req <> fpArb.io.out_req + fpArb.io.out_resp <> fpu.io.cp_resp + } + } + + core.io.rocc.busy := cmdRouter.io.busy || roccs.map(_.io.busy).reduce(_ || _) + core.io.rocc.interrupt := roccs.map(_.io.interrupt).reduce(_ || _) + respArb.io.in <> roccs.map(rocc => Queue(rocc.io.resp)) + + ptwPorts ++= roccs.flatMap(_.io.ptw) + uncachedPorts ++= roccs.flatMap(_.io.utl) } - if (nFPUPorts > 0) { + val uncachedArb = Module(new ClientUncachedTileLinkIOArbiter(uncachedArbPorts.size)) + uncachedArb.io.in <> uncachedArbPorts + uncachedArb.io.out +=: uncachedPorts + + // Connect the caches and RoCC to the outer memory system + io.uncached <> uncachedPorts + io.cached <> cachedPorts + // TODO remove nCached/nUncachedTileLinkPorts parameters and these assertions + require(uncachedPorts.size == nUncachedTileLinkPorts) + require(cachedPorts.size == nCachedTileLinkPorts) + + if (p(UseVM)) { + val ptw = Module(new PTW(ptwPorts.size)(dcacheParams)) + ptw.io.requestor <> ptwPorts + ptw.io.mem +=: dcPorts + core.io.ptw <> ptw.io.dpath + } + + io.slave foreach { case slavePort => + val adapter = Module(new ScratchpadSlavePort()(dcacheParams)) + adapter.io.tl <> TileLinkFragmenter(slavePort) + adapter.io.dmem +=: dcPorts + } + + require(dcPorts.size == core.dcacheArbPorts) + val dcArb = Module(new HellaCacheArbiter(dcPorts.size)(dcacheParams)) + dcArb.io.requestor <> dcPorts + dcache.cpu <> dcArb.io.mem + + if (nFPUPorts == 0) { fpuOpt.foreach { fpu => - val fpArb = Module(new InOrderArbiter(new FPInput, new FPResult, nFPUPorts)) - val fp_roccs = roccs.zip(buildRocc) - .filter { case (_, params) => params.useFPU } - .map { case (rocc, _) => rocc.io } - fpArb.io.in_req <> fp_roccs.map(_.fpu_req) - fp_roccs.zip(fpArb.io.in_resp).foreach { - case (rocc, fpu_resp) => rocc.fpu_resp <> fpu_resp - } - fpu.io.cp_req <> fpArb.io.out_req - fpArb.io.out_resp <> fpu.io.cp_resp + fpu.io.cp_req.valid := Bool(false) + fpu.io.cp_resp.ready := Bool(false) } } - - core.io.rocc.busy := cmdRouter.io.busy || roccs.map(_.io.busy).reduce(_ || _) - core.io.rocc.interrupt := roccs.map(_.io.interrupt).reduce(_ || _) - respArb.io.in <> roccs.map(rocc => Queue(rocc.io.resp)) - - ptwPorts ++= roccs.flatMap(_.io.ptw) - uncachedPorts ++= roccs.flatMap(_.io.utl) - } - - val uncachedArb = Module(new ClientUncachedTileLinkIOArbiter(uncachedArbPorts.size)) - uncachedArb.io.in <> uncachedArbPorts - uncachedArb.io.out +=: uncachedPorts - - // Connect the caches and RoCC to the outer memory system - io.uncached <> uncachedPorts - io.cached <> cachedPorts - // TODO remove nCached/nUncachedTileLinkPorts parameters and these assertions - require(uncachedPorts.size == nUncachedTileLinkPorts) - require(cachedPorts.size == nCachedTileLinkPorts) - - if (p(UseVM)) { - val ptw = Module(new PTW(ptwPorts.size)(dcacheParams)) - ptw.io.requestor <> ptwPorts - ptw.io.mem +=: dcPorts - core.io.ptw <> ptw.io.dpath - } - - io.slave foreach { case slavePort => - val adapter = Module(new ScratchpadSlavePort()(dcacheParams)) - adapter.io.tl <> TileLinkFragmenter(slavePort) - adapter.io.dmem +=: dcPorts - } - - require(dcPorts.size == core.dcacheArbPorts) - val dcArb = Module(new HellaCacheArbiter(dcPorts.size)(dcacheParams)) - dcArb.io.requestor <> dcPorts - dcache.cpu <> dcArb.io.mem - - if (nFPUPorts == 0) { - fpuOpt.foreach { fpu => - fpu.io.cp_req.valid := Bool(false) - fpu.io.cp_resp.ready := Bool(false) - } } }