commit
75c73fce37
@ -289,10 +289,6 @@ trait PeripheryCoreplexLocalInterrupter extends LazyModule with HasPeripheryPara
|
|||||||
val clint = LazyModule(new CoreplexLocalInterrupter(clintConfig)(innerMMIOParams))
|
val clint = LazyModule(new CoreplexLocalInterrupter(clintConfig)(innerMMIOParams))
|
||||||
// The periphery bus is 32-bit, so we may need to adapt its width to XLen
|
// 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)
|
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 {
|
trait PeripheryCoreplexLocalInterrupterBundle {
|
||||||
@ -315,12 +311,8 @@ trait PeripheryBootROM extends LazyModule {
|
|||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
val peripheryBus: TLXbar
|
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)
|
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 {
|
trait PeripheryBootROMBundle {
|
||||||
@ -342,12 +334,8 @@ trait PeripheryTestRAM extends LazyModule {
|
|||||||
val ramBase = 0x52000000
|
val ramBase = 0x52000000
|
||||||
val ramSize = 0x1000
|
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)
|
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 {
|
trait PeripheryTestRAMBundle {
|
||||||
|
@ -27,6 +27,10 @@ abstract class BaseTop(q: Parameters) extends LazyModule {
|
|||||||
val pBusMasters = new RangeManager
|
val pBusMasters = new RangeManager
|
||||||
val pDevices = new ResourceManager[AddrMapEntry]
|
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(
|
lazy val c = CoreplexConfig(
|
||||||
nTiles = q(NTiles),
|
nTiles = q(NTiles),
|
||||||
nExtInterrupts = pInterrupts.sum,
|
nExtInterrupts = pInterrupts.sum,
|
||||||
@ -36,16 +40,14 @@ abstract class BaseTop(q: Parameters) extends LazyModule {
|
|||||||
hasExtMMIOPort = true
|
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})
|
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({
|
implicit val p = qWithMap.alterPartial({
|
||||||
case ConfigString => genConfigString
|
case ConfigString => genConfigString
|
||||||
case NCoreplexExtClients => pBusMasters.sum})
|
case NCoreplexExtClients => pBusMasters.sum})
|
||||||
|
|
||||||
// Add a peripheral bus
|
|
||||||
val peripheryBus = LazyModule(new TLXbar)
|
|
||||||
val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" })))
|
val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" })))
|
||||||
|
|
||||||
peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes))
|
peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes))
|
||||||
|
@ -8,6 +8,7 @@ import uncore.devices._
|
|||||||
import rocket._
|
import rocket._
|
||||||
import rocket.Util._
|
import rocket.Util._
|
||||||
import coreplex._
|
import coreplex._
|
||||||
|
import uncore.tilelink2._
|
||||||
|
|
||||||
import java.nio.file.{Files, Paths}
|
import java.nio.file.{Files, Paths}
|
||||||
import java.nio.{ByteBuffer, ByteOrder}
|
import java.nio.{ByteBuffer, ByteOrder}
|
||||||
@ -51,7 +52,7 @@ class GlobalVariable[T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object GenerateGlobalAddrMap {
|
object GenerateGlobalAddrMap {
|
||||||
def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry]) = {
|
def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry], peripheryManagers: Seq[TLManagerParameters]) = {
|
||||||
lazy val intIOAddrMap: AddrMap = {
|
lazy val intIOAddrMap: AddrMap = {
|
||||||
val entries = collection.mutable.ArrayBuffer[AddrMapEntry]()
|
val entries = collection.mutable.ArrayBuffer[AddrMapEntry]()
|
||||||
entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX)))
|
entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX)))
|
||||||
@ -64,8 +65,21 @@ object GenerateGlobalAddrMap {
|
|||||||
new AddrMap(entries)
|
new AddrMap(entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val tl2AddrMap = new AddrMap(pDevicesEntries, collapse = true)
|
lazy val tl2Devices = peripheryManagers.map { manager =>
|
||||||
lazy val extIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: p(ExtMMIOPorts), collapse = true)
|
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 memBase = 0x80000000L
|
||||||
val memSize = p(ExtMemSize)
|
val memSize = p(ExtMemSize)
|
||||||
@ -80,7 +94,7 @@ object GenerateGlobalAddrMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object GenerateConfigString {
|
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 addrMap = p(GlobalAddrMap)
|
||||||
val plicAddr = addrMap("io:int:plic").start
|
val plicAddr = addrMap("io:int:plic").start
|
||||||
val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:ext:TL2:clint").start)
|
val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:ext:TL2:clint").start)
|
||||||
@ -136,12 +150,13 @@ object GenerateConfigString {
|
|||||||
}
|
}
|
||||||
res append "};\n"
|
res append "};\n"
|
||||||
pDevicesEntries foreach { entry =>
|
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"${entry.name} {\n"
|
||||||
res append s" addr 0x${region.start.toString(16)};\n"
|
res append s" addr 0x${region.start.toString(16)};\n"
|
||||||
res append s" size 0x${region.size.toString(16)}; \n"
|
res append s" size 0x${region.size.toString(16)}; \n"
|
||||||
res append "}\n"
|
res append "}\n"
|
||||||
}
|
}
|
||||||
|
peripheryManagers.foreach { manager => res append manager.dts }
|
||||||
res append '\u0000'
|
res append '\u0000'
|
||||||
res.toString
|
res.toString
|
||||||
}
|
}
|
||||||
|
@ -87,3 +87,6 @@ class CoreplexLocalInterrupter(c: CoreplexLocalInterrupterConfig)(implicit val p
|
|||||||
extends TLRegisterRouter(c.address, 0, c.size, None, c.beatBytes, false)(
|
extends TLRegisterRouter(c.address, 0, c.size, None, c.beatBytes, false)(
|
||||||
new TLRegBundle((c, p), _) with CoreplexLocalInterrupterBundle)(
|
new TLRegBundle((c, p), _) with CoreplexLocalInterrupterBundle)(
|
||||||
new TLRegModule((c, p), _, _) with CoreplexLocalInterrupterModule)
|
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 bundleO(eo: Seq[EO]): Vec[B]
|
||||||
def bundleI(ei: Seq[EI]): Vec[B]
|
def bundleI(ei: Seq[EI]): Vec[B]
|
||||||
def connect(bo: B, eo: EO, bi: B, ei: EI)(implicit sourceInfo: SourceInfo): Unit
|
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
|
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] = {
|
private lazy val oParams : Seq[PO] = {
|
||||||
val o = oFn(oPorts.size, iPorts.map{ case (i, n) => n.oParams(i) })
|
val o = oFn(oPorts.size, iPorts.map{ case (i, n) => n.oParams(i) })
|
||||||
reqE(oPorts.size, o.size)
|
reqE(oPorts.size, o.size)
|
||||||
o
|
o.map(imp.mixO(_, this))
|
||||||
}
|
}
|
||||||
private lazy val iParams : Seq[PI] = {
|
private lazy val iParams : Seq[PI] = {
|
||||||
val i = iFn(iPorts.size, oPorts.map{ case (o, n) => n.iParams(o) })
|
val i = iFn(iPorts.size, oPorts.map{ case (o, n) => n.iParams(o) })
|
||||||
reqE(i.size, iPorts.size)
|
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)) }
|
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,
|
supportsPutPartial: TransferSizes = TransferSizes.none,
|
||||||
supportsHint: 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
|
// 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) =>
|
address.combinations(2).foreach({ case Seq(x,y) =>
|
||||||
require (!x.overlaps(y))
|
require (!x.overlaps(y))
|
||||||
@ -143,6 +144,18 @@ case class TLManagerParameters(
|
|||||||
supportsPutFull.max,
|
supportsPutFull.max,
|
||||||
supportsPutPartial.max).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
|
// The device had better not support a transfer larger than it's alignment
|
||||||
address.foreach({ case a =>
|
address.foreach({ case a =>
|
||||||
require (a.alignment1 >= maxTransfer-1)
|
require (a.alignment1 >= maxTransfer-1)
|
||||||
|
@ -24,6 +24,11 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
|||||||
TLMonitor.legalize(bo, eo)
|
TLMonitor.legalize(bo, eo)
|
||||||
bi <> bo
|
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)
|
case class TLIdentityNode() extends IdentityNode(TLImp)
|
||||||
|
Loading…
Reference in New Issue
Block a user