1
0

coreplex: support multiple memory channels via diplomatic trickery

This commit is contained in:
Wesley W. Terpstra
2017-01-19 14:42:02 -08:00
parent e7b35b4bb6
commit 3a5e5a65f8
7 changed files with 30 additions and 37 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {