From 3a5e5a65f81fe02c7943a5405a262743dfff25ba Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 19 Jan 2017 14:42:02 -0800 Subject: [PATCH] coreplex: support multiple memory channels via diplomatic trickery --- src/main/scala/coreplex/CoreplexNetwork.scala | 12 +++------ src/main/scala/groundtest/Configs.scala | 2 +- src/main/scala/groundtest/TestHarness.scala | 9 ++----- src/main/scala/groundtest/Top.scala | 2 +- src/main/scala/rocketchip/Periphery.scala | 14 +++++----- .../scala/rocketchip/RocketPlexMaster.scala | 2 +- src/main/scala/rocketchip/TestHarness.scala | 26 ++++++++++--------- 7 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/main/scala/coreplex/CoreplexNetwork.scala b/src/main/scala/coreplex/CoreplexNetwork.scala index 2d86f35c..bce3a12e 100644 --- a/src/main/scala/coreplex/CoreplexNetwork.scala +++ b/src/main/scala/coreplex/CoreplexNetwork.scala @@ -70,27 +70,23 @@ trait BankedL2CoherenceManagers extends CoreplexNetwork { require (isPow2(l2Config.nBanksPerChannel)) require (isPow2(l1tol2_lineBytes)) - val mem = Seq.fill(l2Config.nMemoryChannels) { + val mem = TLOutputNode() + for (i <- 0 until l2Config.nMemoryChannels) { val bankBar = LazyModule(new TLXbar) - val output = TLOutputNode() - output := bankBar.node + mem := bankBar.node val mask = ~BigInt((l2Config.nBanksPerChannel-1) * l1tol2_lineBytes) for (i <- 0 until l2Config.nBanksPerChannel) { val (in, out) = l2Config.coherenceManager(p) in := TLFilter(AddressSet(i * l1tol2_lineBytes, mask))(l1tol2.node) bankBar.node := out } - - output } } trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle { val outer: BankedL2CoherenceManagers - - require (l2Config.nMemoryChannels <= 1, "Seq in Chisel Bundle needed to support > 1") // !!! - val mem = outer.mem.map(_.bundleOut).toList.headOption // .headOption should be removed !!! + val mem = outer.mem.bundleOut } trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule { diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 49191416..c539e6b4 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -40,7 +40,7 @@ class MemtestStatelessConfig extends Config( // Test ALL the things class FancyMemtestConfig extends Config( new WithNGenerators(1, 2) ++ new WithNCores(2) ++ new WithMemtest ++ - new WithNMemoryChannels(1) ++ new WithNBanksPerMemChannel(4) ++ // !!! waiting on Chisel3 support for 2 channels + new WithNMemoryChannels(2) ++ new WithNBanksPerMemChannel(4) ++ new WithL2Cache ++ new GroundTestConfig) class CacheFillTestConfig extends Config( diff --git a/src/main/scala/groundtest/TestHarness.scala b/src/main/scala/groundtest/TestHarness.scala index a7f523fe..615a13dc 100644 --- a/src/main/scala/groundtest/TestHarness.scala +++ b/src/main/scala/groundtest/TestHarness.scala @@ -16,11 +16,6 @@ class TestHarness(implicit p: Parameters) extends Module { val dut = Module(LazyModule(new GroundTestTop).module) io.success := dut.io.success - if (dut.io.mem_axi4.nonEmpty) { - val memSize = p(ExtMem).size - require(memSize % dut.io.mem_axi4.size == 0) - for (axi4 <- dut.io.mem_axi4) { - Module(LazyModule(new SimAXIMem(memSize / dut.io.mem_axi4.size)).module).io.axi4 <> axi4 - } - } + val channels = p(coreplex.BankedL2Config).nMemoryChannels + if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4 } diff --git a/src/main/scala/groundtest/Top.scala b/src/main/scala/groundtest/Top.scala index bbd6cd19..5e328089 100644 --- a/src/main/scala/groundtest/Top.scala +++ b/src/main/scala/groundtest/Top.scala @@ -17,7 +17,7 @@ class GroundTestTop(implicit p: Parameters) extends BaseTop socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode - (mem zip coreplex.mem) foreach { case (m, c) => m := c } + mem.foreach { _ := coreplex.mem } } class GroundTestTopBundle[+L <: GroundTestTop](_outer: L) extends BaseTopBundle(_outer) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index bede976d..7402345b 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -87,11 +87,11 @@ trait PeripheryMasterAXI4Mem { private val config = p(ExtMem) private val channels = p(BankedL2Config).nMemoryChannels - val mem_axi4 = Seq.tabulate(channels) { i => + val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(channels) { i => val c_size = config.size/channels val c_base = config.base + c_size*i - AXI4BlindOutputNode(Seq(AXI4SlavePortParameters( + AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( address = List(AddressSet(c_base, c_size-1)), regionType = RegionType.UNCACHED, // cacheable @@ -99,12 +99,12 @@ trait PeripheryMasterAXI4Mem { supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers supportsRead = TransferSizes(1, 256), interleavedId = Some(0))), // slave does not interleave read responses - beatBytes = config.beatBytes))) - } + beatBytes = config.beatBytes) + }) - val mem = mem_axi4.map { node => + val mem = Seq.fill(channels) { val converter = LazyModule(new TLToAXI4(config.idBits)) - node := AXI4Buffer()(converter.node) + mem_axi4 := AXI4Buffer()(converter.node) converter.node } } @@ -113,7 +113,7 @@ trait PeripheryMasterAXI4MemBundle { this: TopNetworkBundle { val outer: PeripheryMasterAXI4Mem } => - val mem_axi4 = outer.mem_axi4.map(_.bundleOut).toList.headOption // !!! remove headOption when Seq supported + val mem_axi4 = outer.mem_axi4.bundleOut } trait PeripheryMasterAXI4MemModule { diff --git a/src/main/scala/rocketchip/RocketPlexMaster.scala b/src/main/scala/rocketchip/RocketPlexMaster.scala index 05a4c331..ff6f7652 100644 --- a/src/main/scala/rocketchip/RocketPlexMaster.scala +++ b/src/main/scala/rocketchip/RocketPlexMaster.scala @@ -19,7 +19,7 @@ trait RocketPlexMaster extends L2Crossbar { coreplex.l2in := l2.node socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode - (mem zip coreplex.mem) foreach { case (m, c) => m := c } + mem.foreach { _ := coreplex.mem } } trait RocketPlexMasterBundle extends L2CrossbarBundle { diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index 35818834..f9569534 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -18,13 +18,8 @@ class TestHarness()(implicit p: Parameters) extends Module { for (int <- dut.io.interrupts(0)) int := Bool(false) - if (dut.io.mem_axi4.nonEmpty) { - val memSize = p(ExtMem).size - require(memSize % dut.io.mem_axi4.size == 0) - for (axi4 <- dut.io.mem_axi4) { - Module(LazyModule(new SimAXIMem(memSize / dut.io.mem_axi4.size)).module).io.axi4 <> axi4 - } - } + val channels = p(coreplex.BankedL2Config).nMemoryChannels + if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4 if (!p(IncludeJtagDTM)) { val dtm = Module(new SimDTM).connect(clock, reset, dut.io.debug.get, io.success) @@ -32,7 +27,7 @@ class TestHarness()(implicit p: Parameters) extends Module { val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, reset, io.success) } - val mmio_sim = Module(LazyModule(new SimAXIMem(4096)).module) + val mmio_sim = Module(LazyModule(new SimAXIMem(1, 4096)).module) mmio_sim.io.axi4 <> dut.io.mmio_axi4 val l2_axi4 = dut.io.l2_axi4(0) @@ -43,12 +38,19 @@ class TestHarness()(implicit p: Parameters) extends Module { l2_axi4.b .ready := Bool(true) } -class SimAXIMem(size: BigInt)(implicit p: Parameters) extends LazyModule { +class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) extends LazyModule { val config = p(ExtMem) + val totalSize = if (forceSize > 0) forceSize else BigInt(config.size) + val size = totalSize / channels + require(totalSize % channels == 0) - val node = AXI4BlindInputNode(Seq(AXI4MasterPortParameters(Seq(AXI4MasterParameters(IdRange(0, 1 << config.idBits)))))) - val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes)) - sram.node := AXI4Buffer()(AXI4Fragmenter(maxInFlight = 4)(node)) + val node = AXI4BlindInputNode(Seq.fill(channels) { + AXI4MasterPortParameters(Seq(AXI4MasterParameters(IdRange(0, 1 << config.idBits))))}) + + for (i <- 0 until channels) { + val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes)) + sram.node := AXI4Buffer()(AXI4Fragmenter(maxInFlight = 4)(node)) + } lazy val module = new LazyModuleImp(this) { val io = new Bundle {