From 806e40d19b24b8753d46d048762b8de58bff428f Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Wed, 6 Jan 2016 21:38:35 -0800 Subject: [PATCH] implement DMA streaming functionality --- groundtest | 2 +- junctions | 2 +- rocket | 2 +- src/main/scala/Configs.scala | 44 ++++++++++++++++++++++++++++---- src/main/scala/DeviceSet.scala | 36 ++++++++++++++++++++++++++ src/main/scala/RocketChip.scala | 28 +++++++++++++++----- src/main/scala/TestConfigs.scala | 16 ++++++++++++ uncore | 2 +- 8 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 src/main/scala/DeviceSet.scala diff --git a/groundtest b/groundtest index 32c9c5f6..5cacda85 160000 --- a/groundtest +++ b/groundtest @@ -1 +1 @@ -Subproject commit 32c9c5f658759e4bb401ac18a5b9c858df6d349f +Subproject commit 5cacda85cf3e5cf07d8cdabdd8a90df2a0a29539 diff --git a/junctions b/junctions index b7706629..ee032b02 160000 --- a/junctions +++ b/junctions @@ -1 +1 @@ -Subproject commit b770662965bcefee5921b482016fd11d4e40f053 +Subproject commit ee032b025af50e5f87ff5da51ad196c354a6b182 diff --git a/rocket b/rocket index f19ab090..63c7f343 160000 --- a/rocket +++ b/rocket @@ -1 +1 @@ -Subproject commit f19ab09004912575372f9680251847e3727d3133 +Subproject commit 63c7f343f28332a8e5286282030ac52ba9fed5b5 diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 7a727449..5291e005 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -29,6 +29,7 @@ class DefaultConfig extends Config ( } def makeDeviceTree() = { val addrMap = new AddrHashMap(site(GlobalAddrMap)) + val devices = site(GlobalDeviceSet) val dt = new DeviceTreeGenerator dt.beginNode("") dt.addProp("#address-cells", 2) @@ -58,6 +59,15 @@ class DefaultConfig extends Config ( dt.addProp("protection", scrs.prot) dt.addReg(scrs.start.toLong, scrs.size.toLong) dt.endNode() + for (dev <- devices.toSeq) { + val entry = addrMap(s"devices:${dev.name}") + dt.beginNode(s"${dev.name}@${entry.start}") + dt.addProp("device_type", s"${dev.dtype}") + dt.addProp("compatible", "riscv") + dt.addProp("protection", entry.prot) + dt.addReg(entry.start.toLong, entry.size.toLong) + dt.endNode() + } dt.endNode() dt.toArray() } @@ -79,7 +89,8 @@ class DefaultConfig extends Config ( case MIFTagBits => // Bits needed at the L2 agent log2Up(site(NAcquireTransactors)+2) + // Bits added by NASTI interconnect - log2Up(site(NMemoryChannels) * site(NBanksPerMemoryChannel) + 1) + log2Up(site(NMemoryChannels) * site(NBanksPerMemoryChannel) + + (if (site(UseDma)) 2 else 1)) case MIFDataBits => 64 case MIFAddrBits => site(PAddrBits) - site(CacheBlockOffsetBits) case MIFDataBeats => site(CacheBlockBytes) * 8 / site(MIFDataBits) @@ -143,6 +154,7 @@ class DefaultConfig extends Config ( case BuildRoCC => Nil case RoccNMemChannels => site(BuildRoCC).map(_.nMemChannels).foldLeft(0)(_ + _) case UseDma => false + case UseStreamLoopback => false case NDmaTransactors => 3 case NDmaClients => site(NTiles) case NDmaXactsPerClient => site(NDmaTransactors) @@ -210,10 +222,21 @@ class DefaultConfig extends Config ( case MMIOBase => Dump("MEM_SIZE", BigInt(1 << 30)) // 1 GB case ExternalIOStart => 2 * site(MMIOBase) case DeviceTree => makeDeviceTree() - case GlobalAddrMap => AddrMap( - AddrMapEntry("mem", None, MemChannels(site(MMIOBase), site(NMemoryChannels), AddrMapConsts.RWX)), - AddrMapEntry("conf", None, MemSubmap(site(ExternalIOStart) - site(MMIOBase), genCsrAddrMap)), - AddrMapEntry("io", Some(site(ExternalIOStart)), MemSize(2 * site(MMIOBase), AddrMapConsts.RW))) + case GlobalAddrMap => { + val extraSize = site(ExternalIOStart) - site(MMIOBase) + AddrMap( + AddrMapEntry("mem", None, MemChannels(site(MMIOBase), site(NMemoryChannels), AddrMapConsts.RWX)), + AddrMapEntry("conf", None, MemSubmap(extraSize / 2, genCsrAddrMap)), + AddrMapEntry("devices", None, MemSubmap(extraSize / 2, site(GlobalDeviceSet).getAddrMap)), + AddrMapEntry("io", Some(site(ExternalIOStart)), MemSize(2 * site(MMIOBase), AddrMapConsts.RW))) + } + case GlobalDeviceSet => { + val devset = new DeviceSet + if (site(UseStreamLoopback)) { + devset.addDevice("loopback", site(StreamLoopbackWidth) / 8, "stream") + } + devset + } }}, knobValues = { case "NTILES" => 1 @@ -384,8 +407,19 @@ class WithDmaController extends Config( case RoccMaxTaggedMemXacts => 1 }) +class WithStreamLoopback extends Config( + (pname, site, here) => pname match { + case UseStreamLoopback => true + case StreamLoopbackSize => 128 + case StreamLoopbackWidth => 64 + }) + class DmaControllerConfig extends Config(new WithDmaController ++ new DefaultL2Config) class SmallL2Config extends Config( new With2MemoryChannels ++ new With4BanksPerMemChannel ++ new WithL2Capacity256 ++ new DefaultL2Config) + +class SingleChannelBenchmarkConfig extends Config(new WithL2Capacity256 ++ new DefaultL2Config) +class DualChannelBenchmarkConfig extends Config(new With2MemoryChannels ++ new SingleChannelBenchmarkConfig) +class QuadChannelBenchmarkConfig extends Config(new With4MemoryChannels ++ new SingleChannelBenchmarkConfig) diff --git a/src/main/scala/DeviceSet.scala b/src/main/scala/DeviceSet.scala new file mode 100644 index 00000000..899b33e1 --- /dev/null +++ b/src/main/scala/DeviceSet.scala @@ -0,0 +1,36 @@ +package rocketchip + +import Chisel.log2Ceil +import cde.{Parameters, Field} +import scala.collection.mutable.HashMap +import junctions._ +import junctions.AddrMapConsts._ + +case object GlobalDeviceSet extends Field[DeviceSet] + +case class Device(name: String, size: Int, dtype: String, + readable: Boolean = true, writeable: Boolean = true) + +class DeviceSet { + val deviceMap = new HashMap[String, Device]() + + def addDevice(name: String, size: Int, dtype: String, readable: Boolean = true, writeable: Boolean = true): Unit = + addDevice(Device(name, size, dtype, readable, writeable)) + + def addDevice(dev: Device): Unit = + deviceMap(dev.name) = dev + + private def roundup(size: Int): Int = (1 << log2Ceil(size)) + + def toSeq: Seq[Device] = deviceMap.values.toSeq + + 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 realsize = roundup(size) + new AddrMapEntry(name, None, new MemSize(realsize, prot)) + } + new AddrMap(entries) + } +} diff --git a/src/main/scala/RocketChip.scala b/src/main/scala/RocketChip.scala index 6fdc69c9..0539a2f7 100644 --- a/src/main/scala/RocketChip.scala +++ b/src/main/scala/RocketChip.scala @@ -32,6 +32,10 @@ case object ExternalIOStart extends Field[BigInt] /** Enable DMA engine */ case object UseDma extends Field[Boolean] +case object UseStreamLoopback extends Field[Boolean] +case object StreamLoopbackSize extends Field[Int] +case object StreamLoopbackWidth extends Field[Int] + /** Utility trait for quick access to some relevant parameters */ trait HasTopLevelParameters { implicit val p: Parameters @@ -213,13 +217,12 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe } val dmaOpt = if (p(UseDma)) Some(Module(new DmaEngine)) else None - dmaOpt.foreach { dma => dma.io.dma <> io.dma } // Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory // Cached ports are first in client list, making sharerToClientId just an indentity function // addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels) val ordered_clients = (io.tiles_cached ++ - (io.tiles_uncached ++ dmaOpt.map(_.io.mem) :+ io.htif_uncached) + (io.tiles_uncached ++ dmaOpt.map(_.io.inner) :+ io.htif_uncached) .map(TileLinkIOWrapper(_))) def sharerToClientId(sharerId: UInt) = sharerId def addrToBank(addr: Bits): UInt = if(nBanks > 1) addr(lsb + log2Up(nBanks) - 1, lsb) else UInt(0) @@ -246,7 +249,7 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe val addrMap = p(GlobalAddrMap) val addrHashMap = new AddrHashMap(addrMap) - val nMasters = managerEndpoints.size + 1 + val nMasters = managerEndpoints.size + (if (dmaOpt.isEmpty) 1 else 2) val nSlaves = addrHashMap.nEntries println("Generated Address Map") @@ -274,6 +277,11 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe val rtc = Module(new RTC(CSRs.mtime)) interconnect.io.masters(nManagers) <> rtc.io + dmaOpt.foreach { dma => + dma.io.dma <> io.dma + interconnect.io.masters(nManagers + 1) <> dma.io.outer + } + for (i <- 0 until nTiles) { val csrName = s"conf:csr$i" val csrPort = addrHashMap(csrName).port @@ -282,9 +290,17 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe io.csr(i) <> conv.io.smi } - val conv = Module(new SMIIONastiIOConverter(scrDataBits, scrAddrBits)) - conv.io.nasti <> interconnect.io.slaves(addrHashMap("conf:scr").port) - io.scr <> conv.io.smi + val src_conv = Module(new SMIIONastiIOConverter(scrDataBits, scrAddrBits)) + src_conv.io.nasti <> interconnect.io.slaves(addrHashMap("conf:scr").port) + io.scr <> src_conv.io.smi + + if (p(UseStreamLoopback)) { + val lo_width = p(StreamLoopbackWidth) + val lo_size = p(StreamLoopbackSize) + val lo_conv = Module(new NastiIOStreamIOConverter(lo_width)) + lo_conv.io.nasti <> interconnect.io.slaves(addrHashMap("devices:loopback").port) + lo_conv.io.stream.in <> Queue(lo_conv.io.stream.out, lo_size) + } io.mmio <> interconnect.io.slaves(addrHashMap("io").port) io.deviceTree <> interconnect.io.slaves(addrHashMap("conf:devicetree").port) diff --git a/src/main/scala/TestConfigs.scala b/src/main/scala/TestConfigs.scala index f0c9a03f..d58e7f6b 100644 --- a/src/main/scala/TestConfigs.scala +++ b/src/main/scala/TestConfigs.scala @@ -4,6 +4,7 @@ import Chisel._ import groundtest._ import rocket._ import uncore._ +import junctions._ import cde.{Parameters, Config, Dump, Knob} import scala.math.max @@ -87,6 +88,20 @@ class WithDmaTest extends Config( case DmaTestDataStride => 8 }) +class WithDmaStreamTest extends Config( + (pname, site, here) => pname match { + case UseDma => true + case BuildGroundTest => + (id: Int, p: Parameters) => Module(new DmaStreamTest()(p)) + case DmaStreamLoopbackAddr => { + val addrMap = new AddrHashMap(site(GlobalAddrMap)) + addrMap("devices:loopback").start + } + case DmaStreamTestSettings => DmaStreamTestConfig( + source = 0x10, dest = 0x28, len = 0x18, + size = site(StreamLoopbackWidth) / 8) + }) + class GroundTestConfig extends Config(new WithGroundTest ++ new DefaultConfig) class MemtestConfig extends Config(new WithMemtest ++ new GroundTestConfig) class MemtestL2Config extends Config( @@ -98,6 +113,7 @@ class BroadcastRegressionTestConfig extends Config( class CacheRegressionTestConfig extends Config( new WithCacheRegressionTest ++ new WithL2Cache ++ new GroundTestConfig) class DmaTestConfig extends Config(new WithDmaTest ++ new WithL2Cache ++ new GroundTestConfig) +class DmaStreamTestConfig extends Config(new WithDmaStreamTest ++ new WithStreamLoopback ++ new WithL2Cache ++ new GroundTestConfig) class FancyMemtestConfig extends Config( new With2Cores ++ new With2MemoryChannels ++ new With2BanksPerMemChannel ++ diff --git a/uncore b/uncore index e41f2ed1..1e6c22a6 160000 --- a/uncore +++ b/uncore @@ -1 +1 @@ -Subproject commit e41f2ed1ad9f12e7f975af37a07b87663ad577a8 +Subproject commit 1e6c22a60c6eccbb85cecadf7503be8eb4c1e476