From d0aa4c722dd94677182927a5ad516eda53d72559 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 28 Apr 2016 16:15:31 -0700 Subject: [PATCH] More WIP on new memory map --- .travis.yml | 1 - csrc/htif_emulator.h | 1 - csrc/vcs_main.rocketTestHarness.cc | 18 +------- junctions | 2 +- rocket | 2 +- src/main/scala/Configs.scala | 72 +++++++++++------------------ src/main/scala/DeviceSet.scala | 5 +- src/main/scala/RocketChip.scala | 73 +++++++++--------------------- src/main/scala/TestConfigs.scala | 4 -- uncore | 2 +- 10 files changed, 55 insertions(+), 125 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25f1ad63..30753b17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,6 @@ env: - CONFIG=DualCoreConfig - CONFIG=MemtestConfig - CONFIG=FancyMemtestConfig - - CONFIG=MemoryMuxMemtestConfig - CONFIG=BroadcastRegressionTestConfig - CONFIG=CacheRegressionTestConfig - CONFIG=NastiConverterTestConfig diff --git a/csrc/htif_emulator.h b/csrc/htif_emulator.h index a948be15..855440f0 100644 --- a/csrc/htif_emulator.h +++ b/csrc/htif_emulator.h @@ -34,7 +34,6 @@ class htif_emulator_t : public htif_pthread_t void start() { set_clock_divisor(5, 2); - write_cr(-1, UNCORE_SCR__MEMORY_CHANNEL_MUX_SELECT__OFFSET, memory_channel_mux_select); htif_pthread_t::start(); } diff --git a/csrc/vcs_main.rocketTestHarness.cc b/csrc/vcs_main.rocketTestHarness.cc index f61cc24d..7752e71b 100644 --- a/csrc/vcs_main.rocketTestHarness.cc +++ b/csrc/vcs_main.rocketTestHarness.cc @@ -14,18 +14,6 @@ extern "C" { extern int vcs_main(int argc, char** argv); -static const int MEMORY_CHANNEL_MUX_CONFIGS[] = { -#ifdef MEMORY_CHANNEL_MUX_CONFIGS__0 - MEMORY_CHANNEL_MUX_CONFIGS__0, -#endif -#ifdef MEMORY_CHANNEL_MUX_CONFIGS__1 - MEMORY_CHANNEL_MUX_CONFIGS__1, -#endif -#ifdef MEMORY_CHANNEL_MUX_CONFIGS__2 -#error "Add a preprocessor repeat macro" -#endif -}; - static htif_emulator_t* htif; static unsigned htif_bytes = HTIF_WIDTH / 8; static mm_t* mm[N_MEM_CHANNELS]; @@ -54,21 +42,19 @@ int main(int argc, char** argv) memory_channel_mux_select = atoi(argv[i]+27); } - int enabled_mem_channels = MEMORY_CHANNEL_MUX_CONFIGS[memory_channel_mux_select]; - htif = new htif_emulator_t(memsz_mb, std::vector(argv + 1, argv + argc)); for (int i=0; iinit(MEM_SIZE / enabled_mem_channels, MEM_DATA_BITS / 8, CACHE_BLOCK_BYTES); + mm[i]->init(MEM_SIZE / N_MEM_CHANNELS, MEM_DATA_BITS / 8, CACHE_BLOCK_BYTES); } if (loadmem) { void *mems[N_MEM_CHANNELS]; for (int i = 0; i < N_MEM_CHANNELS; i++) mems[i] = mm[i]->get_data(); - load_mem(mems, loadmem, CACHE_BLOCK_BYTES, enabled_mem_channels); + load_mem(mems, loadmem, CACHE_BLOCK_BYTES, N_MEM_CHANNELS); } vcs_main(argc, argv); diff --git a/junctions b/junctions index d9c4e92a..30ee6af5 160000 --- a/junctions +++ b/junctions @@ -1 +1 @@ -Subproject commit d9c4e92a21de34515f745893bcb4e76ed8f1cd60 +Subproject commit 30ee6af52cada4fd8579f0654983ac73c1869473 diff --git a/rocket b/rocket index 43baccd1..4aca3088 160000 --- a/rocket +++ b/rocket @@ -1 +1 @@ -Subproject commit 43baccd10a23a4e1e11b3ee0c571bae1729ae035 +Subproject commit 4aca3088510183e344994ce0fc4206e95083a5a7 diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 76422666..3b6a2c46 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -24,36 +24,48 @@ class DefaultConfig extends Config ( topDefinitions = { (pname,site,here) => type PF = PartialFunction[Any,Any] def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname) - def genCsrAddrMap: AddrMap = { - val deviceTree = AddrMapEntry("devicetree", MemSize(1 << 15, AddrMapConsts.R)) - val rtc = AddrMapEntry("rtc", MemSize(1 << 12, AddrMapConsts.RW)) + lazy val internalIOAddrMap: AddrMap = { + val deviceTree = AddrMapEntry("configstring", MemSize(1<<13, 1<<12, MemAttr(AddrMapProt.R))) + val rtc = AddrMapEntry("rtc", MemSize(1<<12, 1<<12, MemAttr(AddrMapProt.RW))) new AddrMap(Seq(deviceTree, rtc)) } + lazy val globalAddrMap: AddrMap = { + val memSize = 1L << 30 + val memAlign = 1L << 31 + val extIOSize = 1L << 29 + val mem = MemSize(memSize, memAlign, MemAttr(AddrMapProt.RWX, true)) + val io = AddrMap( + AddrMapEntry("int", MemSubmap(internalIOAddrMap.computeSize, internalIOAddrMap)), + AddrMapEntry("ext", MemSize(extIOSize, extIOSize, MemAttr(AddrMapProt.RWX)))) + Dump("MEM_SIZE", memSize) + AddrMap( + AddrMapEntry("mem", mem), + AddrMapEntry("io", MemSubmap(io.computeSize, io))) + } def makeConfigString() = { - val addrMap = new AddrHashMap(site(GlobalAddrMap)) + val addrMap = new AddrHashMap(globalAddrMap) val xLen = site(XLen) val res = new StringBuilder - val memSize = addrMap("mem").size - val rtcAddr = addrMap("conf:rtc").start res append "platform {\n" res append " vendor ucb;\n" res append " arch rocket;\n" res append "};\n" res append "rtc {\n" - res append s" addr 0x${rtcAddr.toString(16)};\n" + res append s" addr 0x${addrMap("io:int:rtc").start.toString(16)};\n" res append "};\n" res append "ram {\n" res append " 0 {\n" - res append " addr 0;\n" - res append s" size 0x${memSize.toString(16)};\n" + res append s" addr 0x${addrMap("mem").start.toString(16)};\n" + res append s" size 0x${addrMap("mem").region.size.toString(16)};\n" res append " };\n" res append "};\n" res append "core {\n" for (i <- 0 until site(NTiles)) { - val timecmpAddr = rtcAddr + 8*(i+1) + val isa = s"rv${site(XLen)}ima${if (site(UseFPU)) "fd" else ""}" + val timecmpAddr = addrMap("io:int:rtc").start + 8*(i+1) res append s" $i {\n" res append " 0 {\n" - res append s" isa rv$xLen;\n" + res append s" isa $isa;\n" res append s" timecmp 0x${timecmpAddr.toString(16)};\n" res append " };\n" res append " };\n" @@ -82,7 +94,7 @@ class DefaultConfig extends Config ( // Bits needed at the L2 agent log2Up(site(NAcquireTransactors)+2) + // Bits added by NASTI interconnect - log2Up(site(MaxBanksPerMemoryChannel))) + log2Up(site(NBanksPerMemoryChannel))) case MIFDataBits => Dump("MIF_DATA_BITS", 64) case MIFAddrBits => Dump("MIF_ADDR_BITS", site(PAddrBits) - site(CacheBlockOffsetBits)) @@ -153,7 +165,6 @@ class DefaultConfig extends Config ( case RoccNMemChannels => site(BuildRoCC).map(_.nMemChannels).foldLeft(0)(_ + _) case RoccNPTWPorts => site(BuildRoCC).map(_.nPTWPorts).foldLeft(0)(_ + _) case RoccNCSRs => site(BuildRoCC).map(_.csrs.size).foldLeft(0)(_ + _) - case UseStreamLoopback => false case NDmaTransactors => 3 case NDmaXacts => site(NDmaTransactors) * site(NTiles) case NDmaClients => site(NTiles) @@ -217,7 +228,7 @@ class DefaultConfig extends Config ( dataBits = site(CacheBlockBytes)*8) case TLKey("Outermost") => site(TLKey("L2toMC")).copy( maxClientXacts = site(NAcquireTransactors) + 2, - maxClientsPerPort = site(MaxBanksPerMemoryChannel), + maxClientsPerPort = site(NBanksPerMemoryChannel), dataBeats = site(MIFDataBeats)) case TLKey("L2toMMIO") => { val addrMap = new AddrHashMap(site(GlobalAddrMap)) @@ -236,29 +247,13 @@ class DefaultConfig extends Config ( case NTiles => Knob("NTILES") case NMemoryChannels => Dump("N_MEM_CHANNELS", 1) case NBanksPerMemoryChannel => Knob("NBANKS_PER_MEM_CHANNEL") - case MemoryChannelMuxConfigs => Dump("MEMORY_CHANNEL_MUX_CONFIGS", List( site(NMemoryChannels) )) - case MaxBanksPerMemoryChannel => site(NBanksPerMemoryChannel) * site(NMemoryChannels) / site(MemoryChannelMuxConfigs).sortWith{_ < _}(0) - case NOutstandingMemReqsPerChannel => site(MaxBanksPerMemoryChannel)*(site(NAcquireTransactors)+2) + case NOutstandingMemReqsPerChannel => site(NBanksPerMemoryChannel)*(site(NAcquireTransactors)+2) case BankIdLSB => 0 case CacheBlockBytes => Dump("CACHE_BLOCK_BYTES", 64) case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) case UseHtifClockDiv => true case ConfigString => makeConfigString() - case GlobalAddrMap => { - val memsize = BigInt(1L << 30) - Dump("MEM_SIZE", memsize) - AddrMap( - AddrMapEntry("mem", MemSize(memsize, AddrMapConsts.RWX, true)), - AddrMapEntry("conf", MemSubmap(BigInt(1L << 30), genCsrAddrMap)), - AddrMapEntry("devices", MemSubmap(BigInt(1L << 31), site(GlobalDeviceSet).getAddrMap))) - } - case GlobalDeviceSet => { - val devset = new DeviceSet - if (site(UseStreamLoopback)) { - devset.addDevice("loopback", site(StreamLoopbackWidth) / 8, "stream") - } - devset - } + case GlobalAddrMap => globalAddrMap case _ => throw new CDEMatchError }}, knobValues = { @@ -488,19 +483,6 @@ class OctoChannelBenchmarkConfig extends Config(new With8MemoryChannels ++ new S class EightChannelVLSIConfig extends Config(new With8MemoryChannels ++ new DefaultVLSIConfig) -class WithOneOrMaxChannels extends Config( - (pname, site, here) => pname match { - case MemoryChannelMuxConfigs => Dump("MEMORY_CHANNEL_MUX_CONFIGS", List(1, site(NMemoryChannels))) - case _ => throw new CDEMatchError - } -) -class OneOrEightChannelBenchmarkConfig extends Config(new WithOneOrMaxChannels ++ new With8MemoryChannels ++ new SingleChannelBenchmarkConfig) -class OneOrEightChannelVLSIConfig extends Config(new WithOneOrMaxChannels ++ new EightChannelVLSIConfig) - -class SimulateBackupMemConfig extends Config(){ Dump("MEM_BACKUP_EN", true) } -class BackupMemVLSIConfig extends Config(new SimulateBackupMemConfig ++ new DefaultVLSIConfig) -class OneOrEightChannelBackupMemVLSIConfig extends Config(new WithOneOrMaxChannels ++ new With8MemoryChannels ++ new BackupMemVLSIConfig) - class WithSplitL2Metadata extends Config(knobValues = { case "L2_SPLIT_METADATA" => true; case _ => throw new CDEMatchError }) class SplitL2MetadataTestConfig extends Config(new WithSplitL2Metadata ++ new DefaultL2Config) diff --git a/src/main/scala/DeviceSet.scala b/src/main/scala/DeviceSet.scala index be1dca78..993829cd 100644 --- a/src/main/scala/DeviceSet.scala +++ b/src/main/scala/DeviceSet.scala @@ -4,7 +4,6 @@ import Chisel.log2Ceil import cde.{Parameters, Field} import scala.collection.mutable.HashMap import junctions._ -import junctions.AddrMapConsts._ case object GlobalDeviceSet extends Field[DeviceSet] @@ -27,9 +26,9 @@ class DeviceSet { def getAddrMap: AddrMap = { val devices = this.toSeq.sortWith((a, b) => a.size > b.size) val entries = devices.map { case Device(name, size, _, readable, writeable) => - val prot = (if (readable) R else 0) | (if (writeable) W else 0) + val prot = (if (readable) AddrMapProt.R else 0) | (if (writeable) AddrMapProt.W else 0) val realsize = roundup(size) - new AddrMapEntry(name, new MemSize(realsize, prot)) + AddrMapEntry(name, MemSize(size, roundup(size), MemAttr(prot))) } new AddrMap(entries) } diff --git a/src/main/scala/RocketChip.scala b/src/main/scala/RocketChip.scala index c90f22d8..960f6c47 100644 --- a/src/main/scala/RocketChip.scala +++ b/src/main/scala/RocketChip.scala @@ -17,10 +17,6 @@ case object NTiles extends Field[Int] case object NMemoryChannels extends Field[Int] /** Number of banks per memory channel */ case object NBanksPerMemoryChannel extends Field[Int] -/** Maximum number of banks per memory channel, when configurable */ -case object MaxBanksPerMemoryChannel extends Field[Int] -/** Dynamic memory channel configurations */ -case object MemoryChannelMuxConfigs extends Field[List[Int]] /** Least significant bit of address used for bank partitioning */ case object BankIdLSB extends Field[Int] /** Number of outstanding memory requests */ @@ -61,7 +57,6 @@ trait HasTopLevelParameters { lazy val scrAddrBits = log2Up(nSCR) lazy val scrDataBits = 64 lazy val scrDataBytes = scrDataBits / 8 - lazy val memoryChannelMuxConfigs = p(MemoryChannelMuxConfigs) //require(lsb + log2Up(nBanks) < mifAddrBits) } @@ -80,6 +75,7 @@ class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p) class TopIO(implicit p: Parameters) extends BasicTopIO()(p) { val mem = Vec(nMemChannels, new NastiIO) + val mmio = new NastiIO } object TopUtils { @@ -125,9 +121,11 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters { uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten io.host <> uncore.io.host + io.mmio <> uncore.io.mmio io.mem.zip(uncore.io.mem).foreach { case (outer, inner) => - TopUtils.connectNasti(outer, inner) + outer <> inner // Memory cache type should be normal non-cacheable bufferable + // TODO why is this happening here? Would 0000 (device) be OK instead? outer.ar.bits.cache := UInt("b0011") outer.aw.bits.cache := UInt("b0011") } @@ -165,23 +163,14 @@ class Uncore(implicit val p: Parameters) extends Module val addrMap = p(GlobalAddrMap) val addrHashMap = new AddrHashMap(addrMap) - val memSize = addrHashMap("mem").size val scrFile = Module(new SCRFile("UNCORE_SCR", 0)) scrFile.io.smi <> htif.io.scr scrFile.io.scr.attach(Wire(init = UInt(nTiles)), "N_CORES") - scrFile.io.scr.attach(Wire(init = UInt(memSize >> 20)), "MMIO_BASE") + scrFile.io.scr.attach(Wire(init = UInt(addrHashMap("io:int:configstring").start >> 20)), "MMIO_BASE") // scrFile.io.scr <> (... your SCR connections ...) buildMMIONetwork(p.alterPartial({case TLId => "MMIO_Outermost"})) - // Configures the enabled memory channels. This can't be changed while the - // chip is actively using memory, as it both drops Nasti messages and garbles - // all of memory. - val memory_channel_mux_select = scrFile.io.scr.attach( - Reg(UInt(width = log2Up(memoryChannelMuxConfigs.size))), - "MEMORY_CHANNEL_MUX_SELECT") - outmemsys.io.memory_channel_mux_select := memory_channel_mux_select - // Wire the htif to the memory port(s) and host interface io.mem <> outmemsys.io.mem if(p(UseHtifClockDiv)) { @@ -191,31 +180,26 @@ class Uncore(implicit val p: Parameters) extends Module } def buildMMIONetwork(implicit p: Parameters) = { + val (ioBase, ioAddrMap) = addrHashMap.subMap("io") + val ioAddrHashMap = new AddrHashMap(ioAddrMap, ioBase) + val mmioNarrower = Module(new TileLinkIONarrower("L2toMMIO", "MMIO_Outermost")) - val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, addrMap.tail, memSize)) + val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap, ioBase)) mmioNarrower.io.in <> outmemsys.io.mmio mmioNetwork.io.in.head <> mmioNarrower.io.out - if (p(UseStreamLoopback)) { - val lo_width = p(StreamLoopbackWidth) - val lo_size = p(StreamLoopbackSize) - val lo_conv = Module(new NastiIOStreamIOConverter(lo_width)) - val lo_port = addrHashMap("devices:loopback").port - 1 - TopUtils.connectTilelinkNasti(lo_conv.io.nasti, mmioNetwork.io.out(lo_port)) - lo_conv.io.stream.in <> Queue(lo_conv.io.stream.out, lo_size) - } - val rtc = Module(new RTC(p(NTiles))) - val rtcAddr = addrHashMap("conf:rtc") - val rtcPort = rtcAddr.port - 1 - require(rtc.size <= rtcAddr.size) - rtc.io.tl <> mmioNetwork.io.out(rtcPort) + val rtcAddr = ioAddrHashMap("int:rtc") + require(rtc.size <= rtcAddr.region.size) + rtc.io.tl <> mmioNetwork.io.out(rtcAddr.port) io.timerIRQs := rtc.io.irqs val deviceTree = Module(new ROMSlave(p(ConfigString).toSeq)) - val dtPort = addrHashMap("conf:devicetree").port - 1 - deviceTree.io <> mmioNetwork.io.out(dtPort) + val deviceTreeAddr = ioAddrHashMap("int:configstring") + deviceTree.io <> mmioNetwork.io.out(deviceTreeAddr.port) + + TopUtils.connectTilelinkNasti(io.mmio, mmioNetwork.io.out(ioAddrHashMap("ext").port)) } } @@ -229,7 +213,6 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe val htif_uncached = (new ClientUncachedTileLinkIO).flip val incoherent = Vec(nTiles, Bool()).asInput val mem = Vec(nMemChannels, new NastiIO) - val memory_channel_mux_select = UInt(INPUT, log2Up(memoryChannelMuxConfigs.size)) val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"})) } @@ -272,34 +255,20 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe // TODO: the code to print this stuff should live somewhere else println("Generated Address Map") - for ((name, base, size, _, _) <- addrHashMap.sortedEntries) { - println(f"\t$name%s $base%x - ${base + size - 1}%x") + for ((name, base, region) <- addrHashMap.sortedEntries) { + println(f"\t$name%s $base%x - ${base + region.size - 1}%x") } println("Generated Configuration String") println(new String(p(ConfigString))) - val channelConfigs = p(MemoryChannelMuxConfigs) - require(channelConfigs.sortWith(_ > _)(0) == nMemChannels, - "More memory channels elaborated than can be enabled") - val mem_ic = - if (channelConfigs.size == 1) { - val ic = Module(new TileLinkMemoryInterconnect( - nBanksPerMemChannel, nMemChannels)(outermostTLParams)) - ic - } else { - val nBanks = nBanksPerMemChannel * nMemChannels - val ic = Module(new TileLinkMemorySelector( - nBanks, nMemChannels, channelConfigs)(outermostTLParams)) - ic.io.select := io.memory_channel_mux_select - ic - } + val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, nMemChannels)(outermostTLParams)) - for ((bank, i) <- managerEndpoints.zipWithIndex) { + for ((bank, icPort) <- managerEndpoints zip mem_ic.io.in) { val unwrap = Module(new ClientTileLinkIOUnwrapper()(outerTLParams)) val narrow = Module(new TileLinkIONarrower("L2toMC", "Outermost")) unwrap.io.in <> ClientTileLinkEnqueuer(bank.outerTL, backendBuffering)(outerTLParams) narrow.io.in <> unwrap.io.out - mem_ic.io.in(i) <> narrow.io.out + icPort <> narrow.io.out } for ((nasti, tl) <- io.mem zip mem_ic.io.out) diff --git a/src/main/scala/TestConfigs.scala b/src/main/scala/TestConfigs.scala index 7d740cfc..88479f6f 100644 --- a/src/main/scala/TestConfigs.scala +++ b/src/main/scala/TestConfigs.scala @@ -155,7 +155,3 @@ class TraceGenConfig extends Config(new With2Cores ++ new WithL2Cache ++ new Wit class FancyMemtestConfig extends Config( new With2Cores ++ new With2MemoryChannels ++ new With4BanksPerMemChannel ++ new WithMemtest ++ new WithL2Cache ++ new GroundTestConfig) - -class MemoryMuxMemtestConfig extends Config( - new With2MemoryChannels ++ new WithOneOrMaxChannels ++ - new WithMemtest ++ new GroundTestConfig) diff --git a/uncore b/uncore index 291a0bbf..c57928fa 160000 --- a/uncore +++ b/uncore @@ -1 +1 @@ -Subproject commit 291a0bbf58006bc1d2587c58fa7d63abd7d57083 +Subproject commit c57928fad82beb9e7cab82cb03cf394b24512351