@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user