| @@ -289,10 +289,6 @@ trait PeripheryCoreplexLocalInterrupter extends LazyModule with HasPeripheryPara | ||||
|   val clint = LazyModule(new CoreplexLocalInterrupter(clintConfig)(innerMMIOParams)) | ||||
|   // The periphery bus is 32-bit, so we may need to adapt its width to XLen | ||||
|   clint.node := TLFragmenter(TLWidthWidget(peripheryBus.node, 4), beatBytes, 256) | ||||
|  | ||||
|   // TL1 legacy | ||||
|   val pDevices: ResourceManager[AddrMapEntry] | ||||
|   pDevices.add(AddrMapEntry("clint", MemRange(clintConfig.address, clintConfig.size, MemAttr(AddrMapProt.RW)))) | ||||
| } | ||||
|  | ||||
| trait PeripheryCoreplexLocalInterrupterBundle { | ||||
| @@ -315,12 +311,8 @@ trait PeripheryBootROM extends LazyModule { | ||||
|   implicit val p: Parameters | ||||
|   val peripheryBus: TLXbar | ||||
|  | ||||
|   val rom = LazyModule(new TLROM(0x1000, 0x1000, GenerateBootROM(p))) | ||||
|   val rom = LazyModule(new TLROM(0x1000, 0x1000, GenerateBootROM(p)) { override def name = "bootrom" }) | ||||
|   rom.node := TLFragmenter(peripheryBus.node, 4, 256) | ||||
|  | ||||
|   // TL1 legacy address map | ||||
|   val pDevices: ResourceManager[AddrMapEntry] | ||||
|   pDevices.add(AddrMapEntry("bootrom", MemRange(0x1000, 4096, MemAttr(AddrMapProt.RX)))) | ||||
| } | ||||
|  | ||||
| trait PeripheryBootROMBundle { | ||||
| @@ -342,12 +334,8 @@ trait PeripheryTestRAM extends LazyModule { | ||||
|   val ramBase = 0x52000000 | ||||
|   val ramSize = 0x1000 | ||||
|  | ||||
|   val sram = LazyModule(new TLRAM(AddressSet(ramBase, ramSize-1))) | ||||
|   val sram = LazyModule(new TLRAM(AddressSet(ramBase, ramSize-1)) { override def name = "testram" }) | ||||
|   sram.node := TLFragmenter(peripheryBus.node, 4, 256) | ||||
|  | ||||
|   // TL1 legacy address map | ||||
|   val pDevices: ResourceManager[AddrMapEntry] | ||||
|   pDevices.add(AddrMapEntry("testram", MemRange(ramBase, ramSize, MemAttr(AddrMapProt.RW)))) | ||||
| } | ||||
|  | ||||
| trait PeripheryTestRAMBundle { | ||||
|   | ||||
| @@ -27,6 +27,10 @@ abstract class BaseTop(q: Parameters) extends LazyModule { | ||||
|   val pBusMasters = new RangeManager | ||||
|   val pDevices = new ResourceManager[AddrMapEntry] | ||||
|  | ||||
|   // Add a peripheral bus | ||||
|   val peripheryBus = LazyModule(new TLXbar) | ||||
|   lazy val peripheryManagers = peripheryBus.node.edgesIn(0).manager.managers | ||||
|  | ||||
|   lazy val c = CoreplexConfig( | ||||
|     nTiles = q(NTiles), | ||||
|     nExtInterrupts = pInterrupts.sum, | ||||
| @@ -36,16 +40,14 @@ abstract class BaseTop(q: Parameters) extends LazyModule { | ||||
|     hasExtMMIOPort = true | ||||
|   ) | ||||
|  | ||||
|   lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, pDevices.get) | ||||
|   lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, pDevices.get, peripheryManagers) | ||||
|   private val qWithMap = q.alterPartial({case GlobalAddrMap => genGlobalAddrMap}) | ||||
|  | ||||
|   lazy val genConfigString = GenerateConfigString(qWithMap, c, pDevices.get) | ||||
|   lazy val genConfigString = GenerateConfigString(qWithMap, c, pDevices.get, peripheryManagers) | ||||
|   implicit val p = qWithMap.alterPartial({ | ||||
|     case ConfigString => genConfigString | ||||
|     case NCoreplexExtClients => pBusMasters.sum}) | ||||
|  | ||||
|   // Add a peripheral bus | ||||
|   val peripheryBus = LazyModule(new TLXbar) | ||||
|   val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" }))) | ||||
|  | ||||
|   peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes)) | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import uncore.devices._ | ||||
| import rocket._ | ||||
| import rocket.Util._ | ||||
| import coreplex._ | ||||
| import uncore.tilelink2._ | ||||
|  | ||||
| import java.nio.file.{Files, Paths} | ||||
| import java.nio.{ByteBuffer, ByteOrder} | ||||
| @@ -51,7 +52,7 @@ class GlobalVariable[T] { | ||||
| } | ||||
|  | ||||
| object GenerateGlobalAddrMap { | ||||
|   def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry]) = { | ||||
|   def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry], peripheryManagers: Seq[TLManagerParameters]) = { | ||||
|     lazy val intIOAddrMap: AddrMap = { | ||||
|       val entries = collection.mutable.ArrayBuffer[AddrMapEntry]() | ||||
|       entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX))) | ||||
| @@ -64,8 +65,21 @@ object GenerateGlobalAddrMap { | ||||
|       new AddrMap(entries) | ||||
|     } | ||||
|  | ||||
|     lazy val tl2AddrMap = new AddrMap(pDevicesEntries, collapse = true) | ||||
|     lazy val extIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: p(ExtMMIOPorts), collapse = true) | ||||
|     lazy val tl2Devices = peripheryManagers.map { manager => | ||||
|       val attr = MemAttr( | ||||
|         (if (manager.supportsGet)     AddrMapProt.R else 0) | | ||||
|         (if (manager.supportsPutFull) AddrMapProt.W else 0) | | ||||
|         (if (manager.executable)      AddrMapProt.X else 0)) | ||||
|       val multi = manager.address.size > 1 | ||||
|       manager.address.zipWithIndex.map { case (address, i) => | ||||
|         require (!address.strided) // TL1 can't do this | ||||
|         val name = manager.name + (if (multi) ".%d".format(i) else "") | ||||
|         AddrMapEntry(name, MemRange(address.base, address.mask+1, attr)) | ||||
|       } | ||||
|     }.flatten | ||||
|  | ||||
|     lazy val tl2AddrMap = new AddrMap(tl2Devices, collapse = true) | ||||
|     lazy val extIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: (p(ExtMMIOPorts) ++ pDevicesEntries), collapse = true) | ||||
|  | ||||
|     val memBase = 0x80000000L | ||||
|     val memSize = p(ExtMemSize) | ||||
| @@ -80,7 +94,7 @@ object GenerateGlobalAddrMap { | ||||
| } | ||||
|  | ||||
| object GenerateConfigString { | ||||
|   def apply(p: Parameters, c: CoreplexConfig, pDevicesEntries: Seq[AddrMapEntry]) = { | ||||
|   def apply(p: Parameters, c: CoreplexConfig, pDevicesEntries: Seq[AddrMapEntry], peripheryManagers: Seq[TLManagerParameters]) = { | ||||
|     val addrMap = p(GlobalAddrMap) | ||||
|     val plicAddr = addrMap("io:int:plic").start | ||||
|     val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:ext:TL2:clint").start) | ||||
| @@ -136,12 +150,13 @@ object GenerateConfigString { | ||||
|     } | ||||
|     res append  "};\n" | ||||
|     pDevicesEntries foreach { entry => | ||||
|       val region = addrMap("io:ext:TL2:" + entry.name) | ||||
|       val region = addrMap("io:ext:" + entry.name) | ||||
|       res append s"${entry.name} {\n" | ||||
|       res append s"  addr 0x${region.start.toString(16)};\n" | ||||
|       res append s"  size 0x${region.size.toString(16)}; \n" | ||||
|       res append  "}\n" | ||||
|     } | ||||
|     peripheryManagers.foreach { manager => res append manager.dts } | ||||
|     res append '\u0000' | ||||
|     res.toString | ||||
|   } | ||||
|   | ||||
| @@ -87,3 +87,6 @@ class CoreplexLocalInterrupter(c: CoreplexLocalInterrupterConfig)(implicit val p | ||||
|   extends TLRegisterRouter(c.address, 0, c.size, None, c.beatBytes, false)( | ||||
|   new TLRegBundle((c, p), _)    with CoreplexLocalInterrupterBundle)( | ||||
|   new TLRegModule((c, p), _, _) with CoreplexLocalInterrupterModule) | ||||
| { | ||||
|   override def name = "clint" // defaul is "CoreplexLocalInterrupter" | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,9 @@ abstract class NodeImp[PO, PI, EO, EI, B <: Data] | ||||
|   def bundleO(eo: Seq[EO]): Vec[B] | ||||
|   def bundleI(ei: Seq[EI]): Vec[B] | ||||
|   def connect(bo: B, eo: EO, bi: B, ei: EI)(implicit sourceInfo: SourceInfo): Unit | ||||
|   // If you want to track parameters as they flow through nodes, overload these: | ||||
|   def mixO(po: PO, node: BaseNode[PO, PI, EO, EI, B]): PO = po | ||||
|   def mixI(pi: PI, node: BaseNode[PO, PI, EO, EI, B]): PI = pi | ||||
| } | ||||
|  | ||||
| class RootNode | ||||
| @@ -59,12 +62,12 @@ class BaseNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])( | ||||
|   private lazy val oParams : Seq[PO] = { | ||||
|     val o = oFn(oPorts.size, iPorts.map{ case (i, n) => n.oParams(i) }) | ||||
|     reqE(oPorts.size, o.size) | ||||
|     o | ||||
|     o.map(imp.mixO(_, this)) | ||||
|   } | ||||
|   private lazy val iParams : Seq[PI] = { | ||||
|     val i = iFn(iPorts.size, oPorts.map{ case (o, n) => n.iParams(o) }) | ||||
|     reqE(i.size, iPorts.size) | ||||
|     i | ||||
|     i.map(imp.mixI(_, this)) | ||||
|   } | ||||
|  | ||||
|   lazy val edgesOut = (oPorts zip oParams).map { case ((i, n), o) => imp.edgeO(o, n.iParams(i)) } | ||||
|   | ||||
| @@ -127,7 +127,8 @@ case class TLManagerParameters( | ||||
|   supportsPutPartial: TransferSizes = TransferSizes.none, | ||||
|   supportsHint:       TransferSizes = TransferSizes.none, | ||||
|   // If fifoId=Some, all accesses sent to the same fifoId are executed and ACK'd in FIFO order | ||||
|   fifoId:             Option[Int]   = None) | ||||
|   fifoId:             Option[Int]   = None, | ||||
|   customDTS:          Option[String]= None) | ||||
| { | ||||
|   address.combinations(2).foreach({ case Seq(x,y) => | ||||
|     require (!x.overlaps(y)) | ||||
| @@ -143,6 +144,18 @@ case class TLManagerParameters( | ||||
|     supportsPutFull.max, | ||||
|     supportsPutPartial.max).max | ||||
|  | ||||
|   // Generate the config string (in future device tree) | ||||
|   lazy val name = nodePath.lastOption.map(_.lazyModule.name).getOrElse("disconnected") | ||||
|   lazy val dts = customDTS.getOrElse { | ||||
|     val header = s"${name} {\n" | ||||
|     val middle = address.map { a => | ||||
|       require (!a.strided) // Config String does not support this | ||||
|       "  addr 0x%x;\n  size 0x%x;\n".format(a.base, a.mask+1) | ||||
|     } | ||||
|     val footer = "}\n" | ||||
|     header + middle.reduce(_ + _) + footer | ||||
|   } | ||||
|  | ||||
|   // The device had better not support a transfer larger than it's alignment | ||||
|   address.foreach({ case a => | ||||
|     require (a.alignment1 >= maxTransfer-1) | ||||
|   | ||||
| @@ -24,6 +24,11 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL | ||||
|     TLMonitor.legalize(bo, eo) | ||||
|     bi <> bo | ||||
|   } | ||||
|  | ||||
|   override def mixO(po: TLClientPortParameters,  node: TLBaseNode): TLClientPortParameters  = | ||||
|    po.copy(clients  = po.clients.map  { c => c.copy (nodePath = node +: c.nodePath) }) | ||||
|   override def mixI(pi: TLManagerPortParameters, node: TLBaseNode): TLManagerPortParameters = | ||||
|    pi.copy(managers = pi.managers.map { m => m.copy (nodePath = node +: m.nodePath) }) | ||||
| } | ||||
|  | ||||
| case class TLIdentityNode() extends IdentityNode(TLImp) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user