implement DMA streaming functionality
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
							
								
								
									
										36
									
								
								src/main/scala/DeviceSet.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/main/scala/DeviceSet.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
|   } | ||||
| } | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 ++ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user