1
0
Fork 0

Merge pull request #1190 from freechipsproject/bus-api

BusWrapper API Update
This commit is contained in:
Henry Cook 2018-03-01 01:13:50 -08:00 committed by GitHub
commit 20a8876856
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 749 additions and 672 deletions

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
import freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing}
import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing}
class AXI4AsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
{

View File

@ -1,55 +0,0 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class FrontBusParams(
beatBytes: Int,
blockBytes: Int,
masterBuffering: BufferParams = BufferParams.default,
slaveBuffering: BufferParams = BufferParams.default
) extends TLBusParams
case object FrontBusKey extends Field[FrontBusParams]
class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") {
private val master_buffer = LazyModule(new TLBuffer(params.masterBuffering))
private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
master_buffer.suggestName(s"${busName}_master_TLBuffer")
master_fixer.suggestName(s"${busName}_master_TLFIFOFixer")
master_fixer.node :=* master_buffer.node
inwardNode :=* master_fixer.node
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
}
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
}
def fromCoherentChip: TLInwardNode = inwardNode
def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node
}
/** Provides buses that serve as attachment points,
* for use in traits that connect individual devices or external ports.
*/
trait HasFrontBus extends HasSystemBus {
private val frontbusParams = p(FrontBusKey)
val frontbusBeatBytes = frontbusParams.beatBytes
val fbus = LazyModule(new FrontBus(frontbusParams))
FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus }
}

View File

@ -1,79 +0,0 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
// TODO: applies to all caches, for now
case object CacheBlockBytes extends Field[Int](64)
/** L2 Broadcast Hub configuration */
case class BroadcastParams(
nTrackers: Int = 4,
bufferless: Boolean = false)
case object BroadcastKey extends Field(BroadcastParams())
/** L2 memory subsystem configuration */
case class BankedL2Params(
nMemoryChannels: Int = 1,
nBanksPerChannel: Int = 1,
coherenceManager: HasMemoryBus => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { coreplex =>
implicit val p = coreplex.p
val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey)
val bh = LazyModule(new TLBroadcast(coreplex.memBusBlockBytes, nTrackers, bufferless))
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes))
ww.node :*= bh.node
(bh.node, ww.node, () => None)
}) {
val nBanks = nMemoryChannels*nBanksPerChannel
}
case object BankedL2Key extends Field(BankedL2Params())
/** Parameterization of the memory-side bus created for each memory channel */
case class MemoryBusParams(
beatBytes: Int,
blockBytes: Int,
masterBuffering: BufferParams = BufferParams.none,
slaveBuffering: BufferParams = BufferParams.none
) extends TLBusParams
case object MemoryBusKey extends Field[MemoryBusParams]
/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */
class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "MemoryBus")(p) {
def fromCoherenceManager: TLInwardNode = inwardBufNode
def toDRAMController: TLOutwardNode = outwardBufNode
def toVariableWidthSlave: TLOutwardNode = outwardFragNode
}
trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus {
private val mbusParams = p(MemoryBusKey)
private val l2Params = p(BankedL2Key)
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
val nBanks = l2Params.nBanks
val cacheBlockBytes = memBusBlockBytes
private val (in, out, halt) = coherenceManager(this)
def memBusCanCauseHalt: () => Option[Bool] = halt
require (isPow2(nMemoryChannels) || nMemoryChannels == 0)
require (isPow2(nBanksPerChannel))
require (isPow2(memBusBlockBytes))
private val mask = ~BigInt((nBanks-1) * memBusBlockBytes)
val memBuses = Seq.tabulate(nMemoryChannels) { channel =>
val mbus = LazyModule(new MemoryBus(mbusParams))
for (bank <- 0 until nBanksPerChannel) {
val offset = (bank * nMemoryChannels) + channel
ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus }
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out
}
mbus
}
}

View File

@ -1,61 +0,0 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.config.Field
case class PeripheryBusParams(
beatBytes: Int,
blockBytes: Int,
masterBuffering: BufferParams = BufferParams.default,
slaveBuffering: BufferParams = BufferParams.none,
arithmetic: Boolean = true,
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
) extends TLBusParams {
}
case object PeripheryBusKey extends Field[PeripheryBusParams]
class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") {
def toFixedWidthSingleBeatSlave(widthBytes: Int) = {
TLFragmenter(widthBytes, params.blockBytes) := outwardWWNode
}
def toLargeBurstSlave(maxXferBytes: Int) = {
TLFragmenter(params.beatBytes, maxXferBytes) := outwardBufNode
}
val fromSystemBus: TLInwardNode = {
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node
}
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
this {
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
FlipRendering { implicit p =>
gen(p) :*= outwardNode
}
}
}
}
}
/** Provides buses that serve as attachment points,
* for use in traits that connect individual devices or external ports.
*/
trait HasPeripheryBus extends HasSystemBus {
private val pbusParams = p(PeripheryBusKey)
val pbusBeatBytes = pbusParams.beatBytes
val pbus = LazyModule(new PeripheryBus(pbusParams))
// The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL
pbus.fromSystemBus :*= sbus.toPeripheryBus()
}

View File

@ -1,83 +0,0 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class SystemBusParams(
beatBytes: Int,
blockBytes: Int,
masterBuffering: BufferParams = BufferParams.default,
slaveBuffering: BufferParams = BufferParams.default
) extends TLBusParams
case object SystemBusKey extends Field[SystemBusParams]
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") {
private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks
master_splitter.suggestName(s"${busName}_master_TLSplitter")
inwardNode :=* master_splitter.node
def busView = master_splitter.node.edges.in.head
protected def inwardSplitNode: TLInwardNode = master_splitter.node
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
master_splitter.node :=* port_fixer.node
private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer")
pbus_fixer.node :*= outwardWWNode
def toSplitSlaves: TLOutwardNode = outwardSplitNode
def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = {
TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ :*= _)
}
val toMemoryBus: TLOutwardNode = outwardNode
val toSlave: TLOutwardNode = outwardBufNode
def fromCoherentChip: TLInwardNode = inwardNode
def fromFrontBus: TLInwardNode = master_splitter.node
def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) {
this {
LazyScope(s"${busName}FromTile${name.getOrElse("")}") {
master_splitter.node :=* gen(p)
}
}
}
def fromSyncPorts(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
val buffer = LazyModule(new TLBuffer(params))
name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") }
port_fixer.node :=* buffer.node
buffer.node
}
def fromSyncFIFOMaster(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
fromSyncPorts(params, name)
}
}
/** Provides buses that serve as attachment points,
* for use in traits that connect individual devices or external ports.
*/
trait HasSystemBus extends HasInterruptBus {
private val sbusParams = p(SystemBusKey)
val sbusBeatBytes = sbusParams.beatBytes
val sbus = LazyModule(new SystemBus(sbusParams))
def sharedMemoryTLEdge: TLEdge = sbus.busView
}

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.devices.debug
import Chisel._
import chisel3.core.{IntParam, Input, Output}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.HasPeripheryBus
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.jtag._
@ -26,12 +26,9 @@ class DebugIO(implicit val p: Parameters) extends ParameterizedBundle()(p) with
/** Either adds a JTAG DTM to system, and exports a JTAG interface,
* or exports the Debug Module Interface (DMI), based on a global parameter.
*/
trait HasPeripheryDebug extends HasPeripheryBus {
val module: HasPeripheryDebugModuleImp
trait HasPeripheryDebug { this: BaseSubsystem =>
val debug = LazyModule(new TLDebugModule(pbus.beatBytes))
debug.node := pbus.toVariableWidthSlaves
pbus.toVariableWidthSlave(Some("debug")){ debug.node }
}
trait HasPeripheryDebugBundle {

View File

@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem.{BaseSubsystem, HasResetVectorWire}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
@ -58,8 +58,8 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
}
}
/** Adds a boot ROM that contains the DTB describing the system's coreplex. */
trait HasPeripheryBootROM extends HasPeripheryBus {
/** Adds a boot ROM that contains the DTB describing the system's subsystem. */
trait HasPeripheryBootROM { this: BaseSubsystem =>
val dtb: DTB
private val params = p(BootROMParams)
private lazy val contents = {
@ -71,10 +71,10 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
bootrom.node := pbus.toVariableWidthSlaves
pbus.toVariableWidthSlave(Some("bootrom")){ bootrom.node }
}
/** Coreplex will power-on running at 0x10040 (BootROM) */
/** Subsystem will power-on running at 0x10040 (BootROM) */
trait HasPeripheryBootROMModuleImp extends LazyModuleImp
with HasResetVectorWire {
val outer: HasPeripheryBootROM

View File

@ -4,7 +4,6 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.HasPeripheryBus
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._

View File

@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.HasPeripheryBus
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.tilelink._
@ -12,7 +12,7 @@ import freechips.rocketchip.interrupts._
import freechips.rocketchip.util._
import scala.math.{min,max}
object ClintConsts
object CLINTConsts
{
def msipOffset(hart: Int) = hart * msipBytes
def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes
@ -25,16 +25,16 @@ object ClintConsts
def ints = 2
}
case class ClintParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0)
case class CLINTParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0)
{
def address = AddressSet(baseAddress, ClintConsts.size-1)
def address = AddressSet(baseAddress, CLINTConsts.size-1)
}
case object ClintKey extends Field(ClintParams())
case object CLINTKey extends Field(CLINTParams())
class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule
class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule
{
import ClintConsts._
import CLINTConsts._
// clint0 => at most 4095 devices
val device = new SimpleDevice("clint", Seq("riscv,clint0")) {
@ -90,8 +90,8 @@ class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p:
}
}
/** Trait that will connect a Clint to a coreplex */
trait HasPeripheryClint extends HasPeripheryBus {
val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey), pbus.beatBytes))
clint.node := pbus.toVariableWidthSlaves
/** Trait that will connect a CLINT to a subsystem */
trait HasPeripheryCLINT { this: BaseSubsystem =>
val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes))
pbus.toVariableWidthSlave(Some("clint")) { clint.node }
}

View File

@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.HasSystemBus
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
@ -118,9 +118,8 @@ class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parame
}
}
trait HasSystemErrorSlave extends HasSystemBus {
trait HasSystemErrorSlave { this: BaseSubsystem =>
private val params = p(ErrorParams)
val error = LazyModule(new TLError(params, sbus.beatBytes))
error.node := sbus.toSlave
sbus.toSlave(Some("Error")){ error.node }
}

View File

@ -3,9 +3,9 @@
package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.coreplex.{HasPeripheryBus}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
@ -13,11 +13,11 @@ case class MaskROMParams(address: BigInt, name: String, depth: Int = 2048, width
case object PeripheryMaskROMKey extends Field[Seq[MaskROMParams]]
trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
trait HasPeripheryMaskROMSlave { this: BaseSubsystem =>
val maskROMParams = p(PeripheryMaskROMKey)
val maskROMs = maskROMParams map { params =>
val maskROM = LazyModule(new TLMaskROM(params))
maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes)
pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes, Some("MaskROM")) { maskROM.node }
maskROM
}
}

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.{HasInterruptBus, HasPeripheryBus}
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.tilelink._
@ -268,9 +268,9 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends
}
}
/** Trait that will connect a PLIC to a coreplex */
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
/** Trait that will connect a PLIC to a subsystem */
trait HasPeripheryPLIC { this: BaseSubsystem =>
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
plic.node := pbus.toVariableWidthSlaves
pbus.toVariableWidthSlave(Some("plic")) { plic.node }
plic.intnode := ibus.toPLIC
}

View File

@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.HasMemoryBus
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
@ -46,17 +46,17 @@ case class ZeroParams(base: Long, size: Long, beatBytes: Int)
case object ZeroParams extends Field[ZeroParams]
/** Adds a /dev/null slave that generates zero-filled responses to reads */
trait HasMemoryZeroSlave extends HasMemoryBus {
trait HasMemoryZeroSlave { this: BaseSubsystem =>
private val params = p(ZeroParams)
private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
val zeros = memBuses.map(_.toVariableWidthSlave).zipWithIndex.map { case (node, channel) =>
val zeros = memBuses.zipWithIndex.map { case (bus, channel) =>
val channels = memBuses.size
val base = AddressSet(params.base, params.size-1)
val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes))
val filter = AddressSet(channel * bus.blockBytes, ~((channels-1) * bus.blockBytes))
val address = base.intersect(filter).get
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
zero.node := node
bus.toVariableWidthSlave(Some("Zero")) { zero.node }
zero
}
}

View File

@ -25,50 +25,30 @@ abstract class LazyModule()(implicit val p: Parameters)
parent.foreach(p => p.children = this :: p.children)
// suggestedName accumulates Some(names), taking the final one. Nones are ignored.
private var suggestedName: Option[String] = None
private var suggestedNameVar: Option[String] = None
def suggestName(x: String): this.type = suggestName(Some(x))
def suggestName(x: Option[String]): this.type = {
x.foreach { n => suggestedName = Some(n) }
x.foreach { n => suggestedNameVar = Some(n) }
this
}
private lazy val childNames =
getClass.getMethods.filter { m =>
m.getParameterTypes.isEmpty &&
!java.lang.reflect.Modifier.isStatic(m.getModifiers) &&
m.getName != "children" &&
m.getName != "getChildren"
}.flatMap { m =>
if (classOf[LazyModule].isAssignableFrom(m.getReturnType)) {
val obj = m.invoke(this)
if (obj eq null) Seq() else Seq((m.getName, obj))
} else if (classOf[Seq[LazyModule]].isAssignableFrom(m.getReturnType)) {
val obj = m.invoke(this)
if (obj eq null) Seq() else {
val seq = try { obj.asInstanceOf[Seq[Object]] } catch { case _: Throwable => null }
if (seq eq null) Seq() else {
seq.zipWithIndex.map { case (l, i) => (m.getName + "_" + i, l) }
}
}
} else Seq()
}
private def findValName =
parent.flatMap(_.childNames.find(_._2 eq this)).map(_._1)
private def findClassName(c: Class[_]): String = {
val n = c.getName.split('.').last
if (n.contains('$')) findClassName(c.getSuperclass) else n
}
lazy val className = findClassName(getClass)
lazy val valName = suggestedName.orElse(findValName)
lazy val outerName = if (nodes.size != 1) None else nodes(0).gco.flatMap(_.lazyModule.valName)
lazy val suggestedName = suggestedNameVar.getOrElse(className)
lazy val desiredName = className // + hashcode?
def moduleName = className + valName.orElse(outerName).map("_" + _).getOrElse("")
def instanceName = valName.getOrElse(outerName.map(_ + "_").getOrElse("") + className)
def name = valName.getOrElse(className)
def name = suggestedName // className + suggestedName ++ hashcode ?
def line = sourceLine(info)
// Accessing these names can only be done after circuit elaboration!
lazy val moduleName = module.name // The final Verilog Module name
lazy val pathName = module.pathName
lazy val instanceName = pathName.split('.').last // The final Verilog instance name
def instantiate() { } // a hook for running things in module scope (after children exist, but before dangles+auto exists)
def module: LazyModuleImpLike
@ -79,7 +59,7 @@ abstract class LazyModule()(implicit val p: Parameters)
buf ++= "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:y=\"http://www.yworks.com/xml/graphml\">\n"
buf ++= " <key for=\"node\" id=\"n\" yfiles.type=\"nodegraphics\"/>\n"
buf ++= " <key for=\"edge\" id=\"e\" yfiles.type=\"edgegraphics\"/>\n"
buf ++= " <key for=\"node\" id=\"d\" attr.name=\"NodeDebugString\" attr.type=\"string\"/>\n"
buf ++= " <key for=\"node\" id=\"d\" attr.name=\"Description\" attr.type=\"string\"/>\n"
buf ++= " <graph id=\"G\" edgedefault=\"directed\">\n"
nodesGraphML(buf, " ")
edgesGraphML(buf, " ")
@ -92,11 +72,13 @@ abstract class LazyModule()(implicit val p: Parameters)
private def nodesGraphML(buf: StringBuilder, pad: String) {
buf ++= s"""${pad}<node id=\"${index}\">\n"""
buf ++= s"""${pad} <data key=\"n\"><y:ShapeNode><y:NodeLabel modelName=\"sides\" modelPosition=\"w\" rotationAngle=\"270.0\">${module.instanceName}</y:NodeLabel></y:ShapeNode></data>\n"""
buf ++= s"""${pad} <data key=\"n\"><y:ShapeNode><y:NodeLabel modelName=\"sides\" modelPosition=\"w\" rotationAngle=\"270.0\">${instanceName}</y:NodeLabel></y:ShapeNode></data>\n"""
buf ++= s"""${pad} <data key=\"d\">${moduleName} (${pathName})</data>\n"""
buf ++= s"""${pad} <graph id=\"${index}::\" edgedefault=\"directed\">\n"""
nodes.filter(!_.omitGraphML).foreach { n =>
buf ++= s"""${pad} <node id=\"${index}::${n.index}\">\n"""
buf ++= s"""${pad} <data key=\"d\"><y:ShapeNode><y:Shape type="ellipse"/></y:ShapeNode>${n.nodedebugstring}</data>\n"""
buf ++= s"""${pad} <data key=\"e\"><y:ShapeNode><y:Shape type="Ellipse"/></y:ShapeNode></data>\n"""
buf ++= s"""${pad} <data key=\"d\">${n.nodedebugstring}</data>\n"""
buf ++= s"""${pad} </node>\n"""
}
children.filter(!_.omitGraphML).foreach { _.nodesGraphML(buf, pad + " ") }
@ -149,6 +131,7 @@ object LazyModule
require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}")
scope = bc.parent
bc.info = sourceInfo
if (!bc.suggestedNameVar.isDefined) bc.suggestName(valName.name)
bc
}
}
@ -162,8 +145,8 @@ sealed trait LazyModuleImpLike extends BaseModule
// .module had better not be accessed while LazyModules are still being built!
require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}")
override def desiredName = wrapper.moduleName
suggestName(wrapper.instanceName)
override def desiredName = wrapper.desiredName
suggestName(wrapper.suggestedName)
implicit val p = wrapper.p
@ -186,7 +169,7 @@ sealed trait LazyModuleImpLike extends BaseModule
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
if (d.flipped) { d.data <> io } else { io <> d.data }
d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name)
d.copy(data = io, name = wrapper.suggestedName + "_" + d.name)
}
wrapper.instantiate()
(auto, dangles)

View File

@ -32,7 +32,6 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data]
// optional methods to track node graph
def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters
def getO(pu: UI): Option[BaseNode] = None // most-outward common node
}
// DO = Downwards flowing Parameters generated by the outer side of the node
@ -91,8 +90,6 @@ abstract class BaseNode(implicit val valName: ValName)
if (name.isEmpty) "" else name + "_"
}
protected[diplomacy] def gci: Option[BaseNode] // greatest common inner
protected[diplomacy] def gco: Option[BaseNode] // greatest common outer
def inputs: Seq[(BaseNode, RenderedEdge)]
def outputs: Seq[(BaseNode, RenderedEdge)]
@ -322,9 +319,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
}
}
protected[diplomacy] def gco = if (uiParams.size != 1) None else inner.getO(uiParams(0))
protected[diplomacy] def gci = if (doParams.size != 1) None else outer.getI(doParams(0))
protected[diplomacy] lazy val edgesOut = (oPorts zip doParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.uiParams(i), p, s) }
protected[diplomacy] lazy val edgesIn = (iPorts zip uiParams).map { case ((o, n, p, s), i) => inner.edgeI(n.doParams(o), i, p, s) }

View File

@ -211,7 +211,7 @@ case class Resource(owner: Device, key: String)
}
}
/** The resource binding scope for a LazyModule that generates a device tree (currently Coreplex only). */
/** The resource binding scope for a LazyModule that generates a device tree (currently Subsystem only). */
trait BindingScope
{
this: LazyModule =>

View File

@ -5,13 +5,13 @@ package freechips.rocketchip.groundtest
import Chisel._
import freechips.rocketchip.config.Config
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.rocket.{DCacheParams}
import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
/** Actual testing target Configs */
class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseCoreplexConfig)
class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseSubsystemConfig)
class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)

View File

@ -7,7 +7,7 @@ import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.tile._
@ -15,10 +15,9 @@ import scala.math.max
case object TileId extends Field[Int]
class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem
with HasMasterAXI4MemPort
with HasPeripheryTestRAMSlave
with HasInterruptBus {
with HasPeripheryTestRAMSlave {
val tileParams = p(GroundTestTilesKey)
val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(
c.build(i, p.alterPartial {
@ -28,19 +27,16 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
)}
tiles.flatMap(_.dcacheOpt).foreach { dc =>
sbus.fromTile(None) { implicit p => TileMasterPortParams(addBuffers = 1).adapt(this)(dc.node) }
sbus.fromTile(None, buffers = 1){ dc.node }
}
// No PLIC in ground test; so just sink the interrupts to nowhere
IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes))
pbusRAM.node := pbus.toVariableWidthSlaves
override lazy val module = new GroundTestCoreplexModule(this)
override lazy val module = new GroundTestSubsystemModuleImp(this)
}
class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
with HasMasterAXI4MemPortModuleImp {
val success = IO(Bool(OUTPUT))
@ -51,13 +47,13 @@ class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends Base
}
/** Adds a SRAM to the system for testing purposes. */
trait HasPeripheryTestRAMSlave extends HasPeripheryBus {
trait HasPeripheryTestRAMSlave { this: BaseSubsystem =>
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes))
testram.node := pbus.toVariableWidthSlaves
pbus.toVariableWidthSlave(Some("TestRAM")) { testram.node }
}
/** Adds a fuzzing master to the system for testing purposes. */
trait HasPeripheryTestFuzzMaster extends HasPeripheryBus {
trait HasPeripheryTestFuzzMaster { this: BaseSubsystem =>
val fuzzer = LazyModule(new TLFuzzer(5000))
pbus.bufferFromMasters := fuzzer.node
pbus.fromOtherMaster(Some("Fuzzer")) { fuzzer.node }
}

View File

@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.LazyModule
class TestHarness(implicit p: Parameters) extends Module {
val io = new Bundle { val success = Bool(OUTPUT) }
val dut = Module(LazyModule(new GroundTestCoreplex).module)
val dut = Module(LazyModule(new GroundTestSubsystem).module)
io.success := dut.success
dut.connectSimAXIMem()
}

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.groundtest
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.rocket.{DCache, RocketCoreParams}
import freechips.rocketchip.tile._

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex.CacheBlockBytes
import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.tile.HasCoreParameters
import freechips.rocketchip.util._

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.rocket
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex.{RocketTilesKey}
import freechips.rocketchip.subsystem.{RocketTilesKey}
import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._

View File

@ -7,7 +7,7 @@ import Chisel._
import Chisel.ImplicitConversions._
import chisel3.core.withReset
import freechips.rocketchip.config._
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.tile._

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
import Chisel._
import chisel3.experimental.dontTouch
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex.RocketTilesKey
import freechips.rocketchip.subsystem.RocketTilesKey
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex.CacheBlockBytes
import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._

View File

@ -7,7 +7,7 @@ import Chisel._
import Chisel.ImplicitConversions._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.coreplex.CacheBlockBytes
import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.diplomacy.RegionType
import freechips.rocketchip.tile.{XLen, CoreModule, CoreBundle}
import freechips.rocketchip.tilelink._

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.Parameters
@ -9,14 +9,14 @@ import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.util._
/** BareCoreplex is the root class for creating a coreplex sub-system */
abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope {
/** BareSubsystem is the root class for creating a subsystem */
abstract class BareSubsystem(implicit p: Parameters) extends LazyModule with BindingScope {
lazy val dts = DTS(bindingTree)
lazy val dtb = DTB(dts)
lazy val json = JSON(bindingTree)
}
abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyModuleImp(_outer) {
abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyModuleImp(_outer) {
val outer = _outer
ElaborationArtefacts.add("graphml", outer.graphML)
ElaborationArtefacts.add("dts", outer.dts)
@ -25,16 +25,54 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod
println(outer.dts)
}
/** Base Coreplex class with no peripheral devices or ports added */
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
with HasInterruptBus
with HasSystemBus
with HasPeripheryBus
with HasMemoryBus {
override val module: BaseCoreplexModule[BaseCoreplex]
/** Base Subsystem class with no peripheral devices or ports added */
abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem {
override val module: BaseSubsystemModuleImp[BaseSubsystem]
// These are wrappers around the standard buses available in all subsytems, where
// peripherals, tiles, ports, and other masters and slaves can attach themselves.
val ibus = new InterruptBusWrapper()
val sbus = LazyModule(new SystemBus(p(SystemBusKey)))
val pbus = LazyModule(new PeripheryBus(p(PeripheryBusKey)))
val fbus = LazyModule(new FrontBus(p(FrontBusKey)))
// The sbus masters the pbus; here we convert TL-UH -> TL-UL
pbus.fromSystemBus { sbus.toPeripheryBus { pbus.crossTLIn } }
// The fbus masters the sbus; both are TL-UH or TL-C
FlipRendering { implicit p =>
fbus.toSystemBus { sbus.fromFrontBus { fbus.crossTLOut } }
}
// The sbus masters the mbus; here we convert TL-C -> TL-UH
private val mbusParams = p(MemoryBusKey)
private val l2Params = p(BankedL2Key)
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
val nBanks = l2Params.nBanks
val cacheBlockBytes = memBusBlockBytes
// TODO: the below call to coherenceManager should be wrapped in a LazyScope here,
// but plumbing halt is too annoying for now.
private val (in, out, halt) = coherenceManager(this)
def memBusCanCauseHalt: () => Option[Bool] = halt
require (isPow2(nMemoryChannels) || nMemoryChannels == 0)
require (isPow2(nBanksPerChannel))
require (isPow2(memBusBlockBytes))
private val mask = ~BigInt((nBanks-1) * memBusBlockBytes)
val memBuses = Seq.tabulate(nMemoryChannels) { channel =>
val mbus = LazyModule(new MemoryBus(mbusParams)(p))
for (bank <- 0 until nBanksPerChannel) {
val offset = (bank * nMemoryChannels) + channel
ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } }
mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out
}
mbus
}
// Make topManagers an Option[] so as to avoid LM name reflection evaluating it...
lazy val topManagers = Some(ManagerUnification(sharedMemoryTLEdge.manager.managers))
lazy val topManagers = Some(ManagerUnification(sbus.busView.manager.managers))
ResourceBinding {
val managers = topManagers.get
val max = managers.flatMap(_.address).map(_.max).max
@ -59,9 +97,9 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
}
}
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) {
println("Generated Address Map")
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
private val aw = (outer.sbus.busView.bundle.addressBits-1)/4 + 1
private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s"
private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {

View File

@ -1,7 +1,7 @@
// See LICENSE.SiFive for license details.
// See LICENSE.Berkeley for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config._
@ -13,7 +13,7 @@ import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
class BaseCoreplexConfig extends Config ((site, here, up) => {
class BaseSubsystemConfig extends Config ((site, here, up) => {
// Tile parameters
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
case XLen => 64 // Applies to all cores
@ -23,6 +23,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
case SystemBusKey => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
case PeripheryBusKey => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
case MemoryBusKey => MemoryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
case FrontBusKey => FrontBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
// Additional device Parameters
case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096)
case BootROMParams => BootROMParams(contentFileName = "./bootrom/bootrom.img")
@ -155,8 +156,8 @@ class WithIncoherentTiles extends Config((site, here, up) => {
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
r.copy(master = r.master.copy(cork = Some(true)))
}
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex =>
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes)(coreplex.p))
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { subsystem =>
val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)(subsystem.p))
(ww.node, ww.node, () => None)
})
})
@ -270,10 +271,6 @@ class WithJtagDTM extends Config ((site, here, up) => {
case IncludeJtagDTM => true
})
class WithNoPeripheryArithAMO extends Config ((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey, site).copy(arithmetic = false)
})
class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
})

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config._
@ -11,16 +11,16 @@ import freechips.rocketchip.interrupts._
import freechips.rocketchip.util._
/** Enumerates the three types of clock crossing between tiles and system bus */
sealed trait CoreplexClockCrossing
sealed trait SubsystemClockCrossing
{
def sameClock = this match {
case _: SynchronousCrossing => true
case _ => false
}
}
case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends CoreplexClockCrossing
case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends SubsystemClockCrossing
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends SubsystemClockCrossing
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends SubsystemClockCrossing
private case class CrossingCheck(out: Boolean, source: BaseNode, sink: BaseNode)
@ -45,26 +45,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope
// TileLink
def crossTLSyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = {
val node = this { LazyModule(new TLBuffer(params)).node }
checks = CrossingCheck(out, node, node) :: checks
node
val sync_xing = this { LazyModule(new TLBuffer(params)).node }
checks = CrossingCheck(out, sync_xing, sync_xing) :: checks
sync_xing
}
def crossTLAsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = {
lazy val asource = LazyModule(new TLAsyncCrossingSource(sync))
lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
val source = if (out) this { asource } else asource
val sink = if (out) asink else this { asink }
lazy val async_xing_source = LazyModule(new TLAsyncCrossingSource(sync))
lazy val async_xing_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
val source = if (out) this { async_xing_source } else async_xing_source
val sink = if (out) async_xing_sink else this { async_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
}
def crossTLRationalInOut(out: Boolean)(direction: RationalDirection)(implicit p: Parameters): TLNode = {
lazy val rsource = LazyModule(new TLRationalCrossingSource)
lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
val source = if (out) this { rsource } else rsource
val sink = if (out) rsink else this { rsink }
lazy val rational_xing_source = LazyModule(new TLRationalCrossingSource)
lazy val rational_xing_sink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
val source = if (out) this { rational_xing_source } else rational_xing_source
val sink = if (out) rational_xing_sink else this { rational_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
@ -77,13 +77,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope
def crossTLRationalIn (direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(false)(direction)
def crossTLRationalOut(direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(true )(direction)
def crossTLIn(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
def crossTLIn(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match {
case x: SynchronousCrossing => crossTLSyncIn(x.params)
case x: AsynchronousCrossing => crossTLAsyncIn(x.depth, x.sync)
case x: RationalCrossing => crossTLRationalIn(x.direction)
}
def crossTLOut(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
def crossTLOut(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match {
case x: SynchronousCrossing => crossTLSyncOut(x.params)
case x: AsynchronousCrossing => crossTLAsyncOut(x.depth, x.sync)
case x: RationalCrossing => crossTLRationalOut(x.direction)
@ -92,16 +92,16 @@ trait HasCrossingMethods extends LazyModule with LazyScope
// AXI4
def crossAXI4SyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): AXI4Node = {
val node = this { LazyModule(new AXI4Buffer(params)).node }
checks = CrossingCheck(out, node, node) :: checks
node
val axi4_sync_xing = this { LazyModule(new AXI4Buffer(params)).node }
checks = CrossingCheck(out, axi4_sync_xing, axi4_sync_xing) :: checks
axi4_sync_xing
}
def crossAXI4AsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = {
lazy val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync))
lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
val source = if (out) this { axi4asource } else axi4asource
val sink = if (out) axi4asink else this { axi4asink }
lazy val axi4_async_xing_source = LazyModule(new AXI4AsyncCrossingSource(sync))
lazy val axi4_async_xing_sink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
val source = if (out) this { axi4_async_xing_source } else axi4_async_xing_source
val sink = if (out) axi4_async_xing_sink else this { axi4_async_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
@ -112,13 +112,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope
def crossAXI4AsyncIn (depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(false)(depth, sync)
def crossAXI4AsyncOut(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(true )(depth, sync)
def crossAXI4In(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
def crossAXI4In(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
case x: SynchronousCrossing => crossAXI4SyncIn(x.params)
case x: AsynchronousCrossing => crossAXI4AsyncIn(x.depth, x.sync)
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
}
def crossAXI4Out(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
def crossAXI4Out(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
case x: SynchronousCrossing => crossAXI4SyncOut(x.params)
case x: AsynchronousCrossing => crossAXI4AsyncOut(x.depth, x.sync)
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
@ -127,30 +127,30 @@ trait HasCrossingMethods extends LazyModule with LazyScope
// Interrupts
def crossIntSyncInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
lazy val intssource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val intssink = LazyModule(new IntSyncCrossingSink(0))
val source = if (out) this { intssource } else intssource
val sink = if (out) intssink else this { intssink }
lazy val int_sync_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val int_sync_xing_sink = LazyModule(new IntSyncCrossingSink(0))
val source = if (out) this { int_sync_xing_source } else int_sync_xing_source
val sink = if (out) int_sync_xing_sink else this { int_sync_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
}
def crossIntAsyncInOut(out: Boolean)(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
lazy val intasource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val intasink = LazyModule(new IntSyncCrossingSink(sync))
val source = if (out) this { intasource } else intasource
val sink = if (out) intasink else this { intasink }
lazy val int_async_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val int_async_xing_sink = LazyModule(new IntSyncCrossingSink(sync))
val source = if (out) this { int_async_xing_source } else int_async_xing_source
val sink = if (out) int_async_xing_sink else this { int_async_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
}
def crossIntRationalInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
lazy val intrsource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val intrsink = LazyModule(new IntSyncCrossingSink(1))
val source = if (out) this { intrsource } else intrsource
val sink = if (out) intrsink else this { intrsink }
lazy val int_rational_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
lazy val int_rational_xing_sink = LazyModule(new IntSyncCrossingSink(1))
val source = if (out) this { int_rational_xing_source } else int_rational_xing_source
val sink = if (out) int_rational_xing_sink else this { int_rational_xing_sink }
sink.node :*=* source.node
checks = CrossingCheck(out, source.node, sink.node) :: checks
NodeHandle(source.node, sink.node)
@ -163,26 +163,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope
def crossIntRationalIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(false)(alreadyRegistered)
def crossIntRationalOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(true )(alreadyRegistered)
def crossIntIn(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
def crossIntIn(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
case x: SynchronousCrossing => crossIntSyncIn(alreadyRegistered)
case x: AsynchronousCrossing => crossIntAsyncIn(x.sync, alreadyRegistered)
case x: RationalCrossing => crossIntRationalIn(alreadyRegistered)
}
def crossIntOut(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
def crossIntOut(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
case x: SynchronousCrossing => crossIntSyncOut(alreadyRegistered)
case x: AsynchronousCrossing => crossIntAsyncOut(x.sync, alreadyRegistered)
case x: RationalCrossing => crossIntRationalOut(alreadyRegistered)
}
def crossIntIn (arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false)
def crossIntOut(arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false)
def crossIntIn (arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false)
def crossIntOut(arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false)
}
trait HasCrossing extends HasCrossingMethods
{
this: LazyModule =>
val crossing: CoreplexClockCrossing
val crossing: SubsystemClockCrossing
def crossTLIn (implicit p: Parameters): TLNode = crossTLIn (crossing)
def crossTLOut (implicit p: Parameters): TLNode = crossTLOut (crossing)
@ -195,4 +195,4 @@ trait HasCrossing extends HasCrossingMethods
def crossIntOut(alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntOut(crossing, alreadyRegistered)
}
class CrossingWrapper(val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing
class CrossingWrapper(val crossing: SubsystemClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing

View File

@ -0,0 +1,50 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class FrontBusParams(
beatBytes: Int,
blockBytes: Int,
sbusCrossing: SubsystemClockCrossing = SynchronousCrossing(),
sbusBuffer: BufferParams = BufferParams.default) extends HasTLBusParams
case object FrontBusKey extends Field[FrontBusParams]
class FrontBus(params: FrontBusParams)
(implicit p: Parameters) extends TLBusWrapper(params, "front_bus")
with HasTLXbarPhy
with HasCrossing {
val crossing = params.sbusCrossing
def fromPort[D,U,E,B <: Data]
(name: Option[String] = None, buffers: Int = 1)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("port" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
}
def fromMasterNode(name: Option[String] = None, buffers: Int = 1)(gen: TLOutwardNode) {
from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
}
def fromMaster[D,U,E,B <: Data]
(name: Option[String] = None, buffers: Int = 1)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
}
def fromCoherentChip(gen: => TLNode): TLInwardNode = {
from("coherent_subsystem") { inwardNode :=* gen }
}
def toSystemBus(gen: => TLInwardNode) {
to("sbus") { gen :=* TLBuffer(params.sbusBuffer) :=* outwardNode }
}
}

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import chisel3.experimental.dontTouch
@ -14,12 +14,14 @@ class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
with HasExternallyDrivenTileConstants
with Clocked
trait HasTiles extends HasSystemBus {
trait HasTiles { this: BaseSubsystem =>
implicit val p: Parameters
val tiles: Seq[BaseTile]
protected def tileParams: Seq[TileParams] = tiles.map(_.tileParams)
def nTiles: Int = tileParams.size
def hartIdList: Seq[Int] = tileParams.map(_.hartId)
def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts)
def sharedMemoryTLEdge = sbus.busView
}
trait HasTilesBundle {

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
@ -24,11 +24,6 @@ class InterruptBusWrapper(implicit p: Parameters) {
def toPLIC: IntOutwardNode = int_bus.intnode
}
trait HasInterruptBus {
implicit val p: Parameters
val ibus = new InterruptBusWrapper
}
/** Specifies the number of external interrupts */
case object NExtTopInterrupts extends Field[Int](0)
@ -36,7 +31,7 @@ case object NExtTopInterrupts extends Field[Int](0)
* However, it should not be used directly; instead one of the below
* synchronization wiring child traits should be used.
*/
abstract trait HasExtInterrupts extends HasInterruptBus {
abstract trait HasExtInterrupts { this: BaseSubsystem =>
private val device = new Device with DeviceInterrupts {
def describe(resources: ResourceBindings): Description = {
Description("soc/external-interrupts", describeInterrupts(resources))
@ -50,7 +45,7 @@ abstract trait HasExtInterrupts extends HasInterruptBus {
/** This trait should be used if the External Interrupts have NOT
* already been synchronized to the Periphery (PLIC) Clock.
*/
trait HasAsyncExtInterrupts extends HasExtInterrupts {
trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
if (nExtInterrupts > 0) {
ibus.fromAsync := extInterrupts
}
@ -59,7 +54,7 @@ trait HasAsyncExtInterrupts extends HasExtInterrupts {
/** This trait can be used if the External Interrupts have already been synchronized
* to the Periphery (PLIC) Clock.
*/
trait HasSyncExtInterrupts extends HasExtInterrupts {
trait HasSyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
if (nExtInterrupts > 0) {
ibus.fromSync := extInterrupts
}

View File

@ -0,0 +1,77 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
// TODO: applies to all caches, for now
case object CacheBlockBytes extends Field[Int](64)
/** L2 Broadcast Hub configuration */
case class BroadcastParams(
nTrackers: Int = 4,
bufferless: Boolean = false)
case object BroadcastKey extends Field(BroadcastParams())
/** L2 memory subsystem configuration */
case class BankedL2Params(
nMemoryChannels: Int = 1,
nBanksPerChannel: Int = 1,
coherenceManager: BaseSubsystem => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { subsystem =>
implicit val p = subsystem.p
val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey)
val bh = LazyModule(new TLBroadcast(subsystem.memBusBlockBytes, nTrackers, bufferless))
val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes))
ww.node :*= bh.node
(bh.node, ww.node, () => None)
}) {
val nBanks = nMemoryChannels*nBanksPerChannel
}
case object BankedL2Key extends Field(BankedL2Params())
/** Parameterization of the memory-side bus created for each memory channel */
case class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
case object MemoryBusKey extends Field[MemoryBusParams]
/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */
class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "memory_bus")(p)
with HasTLXbarPhy {
def fromCoherenceManager(
name: Option[String] = None,
buffer: BufferParams = BufferParams.none)
(gen: => TLNode): TLInwardNode = {
from("coherence_manager" named name) {
inwardNode := TLBuffer(buffer) := gen
}
}
def toDRAMController[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[ TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle, D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("memory_controller" named name) { gen := bufferTo(buffer) }
}
def toVariableWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fragmentTo(buffer) }
}
def toFixedWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
}
}

View File

@ -0,0 +1,117 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class PeripheryBusParams(
beatBytes: Int,
blockBytes: Int,
arithmeticAtomics: Boolean = true,
bufferAtomics: BufferParams = BufferParams.default,
sbusCrossingType: SubsystemClockCrossing = SynchronousCrossing(), // relative to sbus
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
) extends HasTLBusParams
case object PeripheryBusKey extends Field[PeripheryBusParams]
class PeripheryBus(params: PeripheryBusParams)
(implicit p: Parameters) extends TLBusWrapper(params, "periphery_bus")
with HasTLXbarPhy
with HasCrossing {
val crossing = params.sbusCrossingType
def toSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= bufferTo(buffer) }
}
def toVariableWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: TLInwardNode) { toVariableWidthSlaveNodeOption(name, buffer)(Some(node)) }
def toVariableWidthSlaveNodeOption(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: Option[TLInwardNode]) {
node foreach { n => to("slave" named name) { n :*= fragmentTo(buffer) } }
}
def toVariableWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fragmentTo(buffer) }
}
def toFixedWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(gen: TLInwardNode) {
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
}
def toFixedWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
}
def toFixedWidthSingleBeatSlaveNode
(widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: TLInwardNode) {
to("slave" named name) {
gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer)
}
}
def toFixedWidthSingleBeatSlave[D,U,E,B <: Data]
(widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) {
gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer)
}
}
def toLargeBurstSlave[D,U,E,B <: Data]
(maxXferBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) {
gen :*= fragmentTo(params.beatBytes, maxXferBytes, buffer)
}
}
def toFixedWidthPort[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("port" named name) { gen := fixedWidthTo(buffer) }
}
def fromSystemBus(gen: => TLOutwardNode) {
from("sbus") {
(inwardNode
:*= TLBuffer(params.bufferAtomics)
:*= TLAtomicAutomata(arithmetic = params.arithmeticAtomics)
:*= gen)
}
}
def fromOtherMaster[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("master" named name) { bufferFrom(buffer) :=* gen }
}
def toTile
(name: Option[String] = None, buffers: Int = 0)
(gen: => TLNode): TLOutwardNode = {
to("tile" named name) { FlipRendering { implicit p =>
gen :*= bufferTo(buffers)
}}
}
}

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
@ -27,11 +27,13 @@ case object ExtIn extends Field[SlavePortParams]
///// The following traits add ports to the sytem, in some cases converting to different interconnect standards
/** Adds a port to the system intended to master an AXI4 DRAM controller. */
trait HasMasterAXI4MemPort extends HasMemoryBus {
trait HasMasterAXI4MemPort { this: BaseSubsystem =>
val module: HasMasterAXI4MemPortModuleImp
private val params = p(ExtMem)
private val portName = "axi4"
private val device = new MemoryDevice
val nMemoryChannels: Int
val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet(params.base, params.size-1)
@ -49,13 +51,10 @@ trait HasMasterAXI4MemPort extends HasMemoryBus {
beatBytes = params.beatBytes)
})
val converter = LazyModule(new TLToAXI4())
val trim = LazyModule(new AXI4IdIndexer(params.idBits))
val yank = LazyModule(new AXI4UserYanker)
val buffer = LazyModule(new AXI4Buffer)
memBuses.map(_.toDRAMController).foreach { case node =>
mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node
memBuses.map { m =>
mem_axi4 := m.toDRAMController(Some(portName)) {
(AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4())
}
}
}
@ -75,15 +74,17 @@ trait HasMasterAXI4MemPortBundle {
/** Actually generates the corresponding IO in the concrete Module */
trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle {
val outer: HasMasterAXI4MemPort
val mem_axi4 = IO(HeterogeneousBag.fromNode(outer.mem_axi4.in))
(mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o }
val nMemoryChannels = outer.nMemoryChannels
}
/** Adds a AXI4 port to the system intended to master an MMIO device bus */
trait HasMasterAXI4MMIOPort extends HasSystemBus {
trait HasMasterAXI4MMIOPort { this: BaseSubsystem =>
private val params = p(ExtBus)
private val device = new SimpleBus("mmio", Nil)
private val portName = "mmio_port_axi4"
private val device = new SimpleBus(portName.kebab, Nil)
val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = AddressSet.misaligned(params.base, params.size),
@ -93,13 +94,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus {
supportsRead = TransferSizes(1, params.maxXferBytes))),
beatBytes = params.beatBytes)))
(mmio_axi4
:= AXI4Buffer()
:= AXI4UserYanker()
:= AXI4Deinterleaver(sbus.blockBytes)
:= AXI4IdIndexer(params.idBits)
:= TLToAXI4()
:= sbus.toFixedWidthPorts)
mmio_axi4 := sbus.toFixedWidthPort(Some(portName)) {
(AXI4Buffer()
:= AXI4UserYanker()
:= AXI4Deinterleaver(sbus.blockBytes)
:= AXI4IdIndexer(params.idBits)
:= TLToAXI4())
}
}
/** Common io name and methods for propagating or tying off the port bundle */
@ -120,21 +121,22 @@ trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMI
}
/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */
trait HasSlaveAXI4Port extends HasSystemBus {
trait HasSlaveAXI4Port { this: BaseSubsystem =>
private val params = p(ExtIn)
private val portName = "slave_port_axi4"
val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
masters = Seq(AXI4MasterParameters(
name = "AXI4 periphery",
name = portName.kebab,
id = IdRange(0, 1 << params.idBits))))))
private val fifoBits = 1
(sbus.fromSyncPorts()
:= TLWidthWidget(params.beatBytes)
:= AXI4ToTL()
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
:= AXI4Fragmenter()
:= AXI4IdIndexer(fifoBits)
:= l2FrontendAXI4Node)
sbus.fromPort(Some(portName)) {
(TLWidthWidget(params.beatBytes)
:= AXI4ToTL()
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
:= AXI4Fragmenter()
:= AXI4IdIndexer(fifoBits))
} := l2FrontendAXI4Node
}
/** Common io name and methods for propagating or tying off the port bundle */
@ -160,9 +162,10 @@ trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundl
}
/** Adds a TileLink port to the system intended to master an MMIO device bus */
trait HasMasterTLMMIOPort extends HasSystemBus {
trait HasMasterTLMMIOPort { this: BaseSubsystem =>
private val params = p(ExtBus)
private val device = new SimpleBus("mmio", Nil)
private val portName = "mmio_port_tl"
private val device = new SimpleBus(portName.kebab, Nil)
val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters(
managers = Seq(TLManagerParameters(
address = AddressSet.misaligned(params.base, params.size),
@ -173,7 +176,9 @@ trait HasMasterTLMMIOPort extends HasSystemBus {
supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
beatBytes = params.beatBytes)))
mmio_tl := TLBuffer() := TLSourceShrinker(1 << params.idBits) := sbus.toFixedWidthPorts
mmio_tl := sbus.toFixedWidthPort(Some(portName)) {
TLBuffer() := TLSourceShrinker(1 << params.idBits)
}
}
/** Common io name and methods for propagating or tying off the port bundle */
@ -201,14 +206,17 @@ trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPor
/** Adds an TL port to the system intended to be a slave on an MMIO device bus.
* NOTE: this port is NOT allowed to issue Acquires.
*/
trait HasSlaveTLPort extends HasSystemBus {
trait HasSlaveTLPort { this: BaseSubsystem =>
private val params = p(ExtIn)
private val portName = "slave_port_tl"
val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters(
clients = Seq(TLClientParameters(
name = "Front Port (TL)",
name = portName.kebab,
sourceId = IdRange(0, 1 << params.idBits))))))
sbus.fromSyncPorts() := TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) := l2FrontendTLNode
sbus.fromPort(Some(portName)) {
TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes)
} := l2FrontendTLNode
}
/** Common io name and methods for propagating or tying off the port bundle */

View File

@ -1,13 +1,13 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
import freechips.rocketchip.devices.tilelink.HasPeripheryCLINT
trait HasRTCModuleImp extends LazyModuleImp {
val outer: HasPeripheryClint
val outer: BaseSubsystem with HasPeripheryCLINT
private val pbusFreq = outer.p(PeripheryBusKey).frequency
private val rtcFreq = outer.p(DTSTimebase)
private val internalPeriod: BigInt = pbusFreq / rtcFreq

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._

View File

@ -1,6 +1,6 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.coreplex
package freechips.rocketchip.subsystem
import Chisel._
import chisel3.internal.sourceinfo.SourceInfo
@ -14,41 +14,11 @@ import freechips.rocketchip.interrupts._
import freechips.rocketchip.util._
// TODO: how specific are these to RocketTiles?
case class TileMasterPortParams(
addBuffers: Int = 0,
cork: Option[Boolean] = None) {
def adapt(coreplex: HasPeripheryBus)
(masterNode: TLOutwardNode)
(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
(Seq(tile_master_fixer.node) ++ TLBuffer.chain(addBuffers) ++ tile_master_cork.map(_.node))
.foldRight(masterNode)(_ :=* _)
}
}
case class TileSlavePortParams(
addBuffers: Int = 0,
blockerCtrlAddr: Option[BigInt] = None) {
def adapt(coreplex: HasPeripheryBus)
(slaveNode: TLInwardNode)
(implicit p: Parameters, sourceInfo: SourceInfo): TLInwardNode = {
val tile_slave_blocker =
blockerCtrlAddr
.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
.map(bp => LazyModule(new BasicBusBlocker(bp)))
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
(Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers))
.foldLeft(slaveNode)(_ :*= _)
}
}
case class TileMasterPortParams(buffers: Int = 0, cork: Option[Boolean] = None)
case class TileSlavePortParams(buffers: Int = 0, blockerCtrlAddr: Option[BigInt] = None)
case class RocketCrossingParams(
crossingType: CoreplexClockCrossing = SynchronousCrossing(),
crossingType: SubsystemClockCrossing = SynchronousCrossing(),
master: TileMasterPortParams = TileMasterPortParams(),
slave: TileSlavePortParams = TileSlavePortParams()) {
def knownRatio: Option[Int] = crossingType match {
@ -61,10 +31,9 @@ case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))
trait HasRocketTiles extends HasTiles
with HasPeripheryBus
with HasPeripheryPLIC
with HasPeripheryClint
with HasPeripheryDebug {
with HasPeripheryCLINT
with HasPeripheryDebug { this: BaseSubsystem =>
val module: HasRocketTilesModuleImp
protected val rocketTileParams = p(RocketTilesKey)
@ -95,7 +64,7 @@ trait HasRocketTiles extends HasTiles
def tileMasterBuffering: TLOutwardNode = rocket {
// The buffers needed to cut feed-through paths are microarchitecture specific, so belong here
val masterBuffer = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1)))
val masterBufferNode = TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1))
crossing.crossingType match {
case _: AsynchronousCrossing => rocket.masterNode
case SynchronousCrossing(b) =>
@ -104,28 +73,41 @@ trait HasRocketTiles extends HasTiles
case RationalCrossing(dir) =>
require (dir != SlowToFast, "Misconfiguration? Core slower than fabric")
if (tp.boundaryBuffers) {
masterBuffer.node :=* rocket.masterNode
masterBufferNode :=* rocket.masterNode
} else {
rocket.masterNode
}
}
}
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) }
sbus.fromTile(tp.name, crossing.master.buffers) {
crossing.master.cork
.map { u => TLCacheCork(unsafe = u) }
.map { _ :=* rocket.crossTLOut }
.getOrElse { rocket.crossTLOut }
} :=* tileMasterBuffering
// Connect the slave ports of the tile to the periphery bus
def tileSlaveBuffering: TLInwardNode = rocket {
val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
val slaveBufferNode = TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)
crossing.crossingType match {
case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBuffer.node
case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBufferNode
case _ => rocket.slaveNode
}
}
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)( DisableMonitors { implicit p =>
tileSlaveBuffering :*= rocket.crossTLIn
})}
DisableMonitors { implicit p =>
tileSlaveBuffering :*= pbus.toTile(tp.name) {
crossing.slave.blockerCtrlAddr
.map { BasicBusBlockerParams(_, pbus.beatBytes, sbus.beatBytes) }
.map { bbbp => LazyModule(new BasicBusBlocker(bbbp)) }
.map { bbb =>
pbus.toVariableWidthSlave(Some("bus_blocker")) { bbb.controlNode }
rocket.crossTLIn :*= bbb.node
} .getOrElse { rocket.crossTLIn }
}
}
// Handle all the different types of interrupts crossing to or from the tile:
// 1. Debug interrupt is definitely asynchronous in all cases.
@ -163,13 +145,13 @@ trait HasRocketTilesModuleImp extends HasTilesModuleImp
val outer: HasRocketTiles
}
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem
with HasRocketTiles {
val tiles = rocketTiles
override lazy val module = new RocketCoreplexModule(this)
override lazy val module = new RocketSubsystemModuleImp(this)
}
class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
with HasRocketTilesModuleImp {
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
wire.clock := clock

View File

@ -0,0 +1,109 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.subsystem
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class SystemBusParams(
beatBytes: Int,
blockBytes: Int,
pbusBuffer: BufferParams = BufferParams.none) extends HasTLBusParams
case object SystemBusKey extends Field[SystemBusParams]
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "system_bus")
with HasTLXbarPhy {
private val master_splitter = LazyModule(new TLSplitter)
inwardNode :=* master_splitter.node
protected def fixFromThenSplit(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode =
master_splitter.node :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _)
def busView = master_splitter.node.edges.in.head
def toPeripheryBus(gen: => TLNode): TLOutwardNode = {
to("pbus") {
(gen
:= TLFIFOFixer(TLFIFOFixer.all)
:= TLWidthWidget(params.beatBytes)
:= bufferTo(params.pbusBuffer))
}
}
def toMemoryBus(gen: => TLInwardNode) {
to("mbus") { gen := delayNode := outwardNode }
}
def toSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= bufferTo(buffer) }
}
def toSplitSlave[D,U,E,B <: Data]
(name: Option[String] = None)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :=* master_splitter.node }
}
def toFixedWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
}
def toVariableWidthSlave[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("slave" named name) { gen :*= fragmentTo(buffer) }
}
def fromFrontBus(gen: => TLNode): TLInwardNode = {
from("front_bus") { master_splitter.node :=* gen }
}
def fromTile
(name: Option[String], buffers: Int = 0, cork: Option[Boolean] = None)
(gen: => TLNode): TLInwardNode = {
from("tile" named name) {
fixFromThenSplit(TLFIFOFixer.allUncacheable, buffers) :=* gen
}
}
def toFixedWidthPort[D,U,E,B <: Data]
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
to("port" named name) { gen := fixedWidthTo(buffer) }
}
def fromPort[D,U,E,B <: Data]
(name: Option[String] = None, buffers: Int = 0)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("port" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen }
}
def fromCoherentMaster[D,U,E,B <: Data]
(name: Option[String] = None, buffers: Int = 0)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("coherent_master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
}
def fromMaster[D,U,E,B <: Data]
(name: Option[String] = None, buffers: Int = 0)
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
from("master" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen }
}
}

View File

@ -5,13 +5,13 @@ package freechips.rocketchip.system
import Chisel._
import freechips.rocketchip.config.Config
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey}
import freechips.rocketchip.diplomacy._
class WithJtagDTMSystem extends freechips.rocketchip.coreplex.WithJtagDTM
class WithJtagDTMSystem extends freechips.rocketchip.subsystem.WithJtagDTM
class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => {
class BaseConfig extends Config(new BaseSubsystemConfig().alter((site,here,up) => {
// DTS descriptive parameters
case DTSModel => "freechips,rocketchip-unknown"
case DTSCompat => Nil

View File

@ -4,22 +4,22 @@ package freechips.rocketchip.system
import Chisel._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.util.DontTouch
/** Example Top with periphery devices and ports, and a Rocket coreplex */
class ExampleRocketSystem(implicit p: Parameters) extends RocketCoreplex
/** Example Top with periphery devices and ports, and a Rocket subsystem */
class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem
with HasAsyncExtInterrupts
with HasMasterAXI4MemPort
with HasMasterAXI4MMIOPort
with HasSlaveAXI4Port
with HasPeripheryBootROM
with HasSystemErrorSlave {
override lazy val module = new ExampleRocketSystemModule(this)
override lazy val module = new ExampleRocketSystemModuleImp(this)
}
class ExampleRocketSystemModule[+L <: ExampleRocketSystem](_outer: L) extends RocketCoreplexModule(_outer)
class ExampleRocketSystemModuleImp[+L <: ExampleRocketSystem](_outer: L) extends RocketSubsystemModuleImp(_outer)
with HasRTCModuleImp
with HasExtInterruptsModuleImp
with HasMasterAXI4MemPortModuleImp

View File

@ -2,13 +2,13 @@
package freechips.rocketchip.system
import freechips.rocketchip.coreplex.RocketTilesKey
import freechips.rocketchip.subsystem.RocketTilesKey
import freechips.rocketchip.tile.XLen
import freechips.rocketchip.util.GeneratorApp
import scala.collection.mutable.LinkedHashSet
/** A Generator for platforms containing Rocket Coreplexes */
/** A Generator for platforms containing Rocket Subsystemes */
object Generator extends GeneratorApp {
val rv64RegrTestNames = LinkedHashSet(
@ -50,7 +50,7 @@ object Generator extends GeneratorApp {
override def addTestSuites {
import DefaultTestSuites._
val xlen = params(XLen)
// TODO: for now only generate tests for the first core in the first coreplex
// TODO: for now only generate tests for the first core in the first subsystem
val tileParams = params(RocketTilesKey).head
val coreParams = tileParams.core
val vm = coreParams.useVM

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.tile
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.rocket._
@ -122,7 +122,7 @@ trait HasTileParameters {
}
/** Base class for all Tiles that use TileLink */
abstract class BaseTile(tileParams: TileParams, val crossing: CoreplexClockCrossing)
abstract class BaseTile(tileParams: TileParams, val crossing: SubsystemClockCrossing)
(implicit p: Parameters) extends LazyModule with HasTileParameters with HasCrossing
{
def module: BaseTileModuleImp[BaseTile]

View File

@ -18,7 +18,7 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
val lip = Vec(coreParams.nLocalInterrupts, Bool())
}
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
// Use diplomatic interrupts to external interrupts from the subsystem into the tile
trait HasExternalInterrupts { this: BaseTile =>
val intInwardNode = intXbar.intnode
@ -50,7 +50,7 @@ trait HasExternalInterrupts { this: BaseTile =>
// TODO: the order of the following two functions must match, and
// also match the order which things are connected to the
// per-tile crossbar in coreplex.HasRocketTiles
// per-tile crossbar in subsystem.HasRocketTiles
// debug, msip, mtip, meip, seip, lip offsets in CSRs
def csrIntMap: List[Int] = {

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.tile
import Chisel._
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.coreplex.CacheBlockBytes
import freechips.rocketchip.subsystem.CacheBlockBytes
import freechips.rocketchip.tilelink.ClientMetadata
import freechips.rocketchip.util._

View File

@ -6,7 +6,7 @@ package freechips.rocketchip.tile
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.coreplex._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.rocket._
import freechips.rocketchip.tilelink._

View File

@ -5,7 +5,7 @@ package freechips.rocketchip.tile
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.coreplex.CoreplexClockCrossing
import freechips.rocketchip.subsystem.SubsystemClockCrossing
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
@ -33,7 +33,7 @@ case class RocketTileParams(
class RocketTile(
val rocketParams: RocketTileParams,
crossing: CoreplexClockCrossing)
crossing: SubsystemClockCrossing)
(implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p)
with HasExternalInterrupts
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util._
import freechips.rocketchip.util.property._
import freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing}
import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing}
class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
{

View File

@ -1,85 +0,0 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
case object TLBusDelayProbability extends Field[Double](0.0)
/** Specifies widths of various attachement points in the SoC */
trait TLBusParams {
val beatBytes: Int
val blockBytes: Int
val masterBuffering: BufferParams
val slaveBuffering: BufferParams
def beatBits: Int = beatBytes * 8
def blockBits: Int = blockBytes * 8
def blockBeats: Int = blockBytes / beatBytes
def blockOffset: Int = log2Up(blockBytes)
}
abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters)
extends SimpleLazyModule with LazyScope with TLBusParams {
val beatBytes = params.beatBytes
val blockBytes = params.blockBytes
val masterBuffering = params.masterBuffering
val slaveBuffering = params.slaveBuffering
require(blockBytes % beatBytes == 0)
private val delayProb = p(TLBusDelayProbability)
protected val xbar = LazyModule(new TLXbar)
xbar.suggestName(busName)
private val master_buffer = LazyModule(new TLBuffer(masterBuffering))
master_buffer.suggestName(s"${busName}_master_TLBuffer")
private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering))
slave_buffer.suggestName(s"${busName}_slave_TLBuffer")
private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes))
slave_frag.suggestName(s"${busName}_slave_TLFragmenter")
private val slave_ww = LazyModule(new TLWidthWidget(beatBytes))
slave_ww.suggestName(s"${busName}_slave_TLWidthWidget")
private val delayedNode = if (delayProb > 0.0) {
val firstDelay = LazyModule(new TLDelayer(delayProb))
val flowDelay = LazyModule(new TLBuffer(BufferParams.flow))
val secondDelay = LazyModule(new TLDelayer(delayProb))
firstDelay.node :*= xbar.node
flowDelay.node :*= firstDelay.node
secondDelay.node :*= flowDelay.node
secondDelay.node
} else {
xbar.node
}
xbar.node :=* master_buffer.node
slave_buffer.node :*= delayedNode
slave_frag.node :*= slave_buffer.node
slave_ww.node :*= slave_buffer.node
protected def outwardNode: TLOutwardNode = delayedNode
protected def outwardBufNode: TLOutwardNode = slave_buffer.node
protected def outwardFragNode: TLOutwardNode = slave_frag.node
protected def outwardWWNode: TLOutwardNode = slave_ww.node
protected def inwardNode: TLInwardNode = xbar.node
protected def inwardBufNode: TLInwardNode = master_buffer.node
def bufferFromMasters: TLInwardNode = inwardBufNode
def bufferToSlaves: TLOutwardNode = outwardBufNode
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = {
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _)
}
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
def toFixedWidthSlaves: TLOutwardNode = outwardWWNode
def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions
}

View File

@ -0,0 +1,87 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
case object TLBusDelayProbability extends Field[Double](0.0)
/** Specifies widths of various attachement points in the SoC */
trait HasTLBusParams {
val beatBytes: Int
val blockBytes: Int
def beatBits: Int = beatBytes * 8
def blockBits: Int = blockBytes * 8
def blockBeats: Int = blockBytes / beatBytes
def blockOffset: Int = log2Up(blockBytes)
}
abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implicit p: Parameters)
extends SimpleLazyModule with LazyScope with HasTLBusParams {
val beatBytes = params.beatBytes
val blockBytes = params.blockBytes
require(blockBytes % beatBytes == 0)
protected def inwardNode: TLInwardNode
protected def outwardNode: TLOutwardNode
protected def bufferFrom(buffer: BufferParams): TLInwardNode =
inwardNode :=* TLBuffer(buffer)
protected def bufferFrom(buffers: Int): TLInwardNode =
TLBuffer.chain(buffers).foldLeft(inwardNode)(_ :=* _)
protected def fixFrom(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode =
inwardNode :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _)
protected def bufferTo(buffer: BufferParams): TLOutwardNode =
TLBuffer(buffer) :*= delayNode :*= outwardNode
protected def bufferTo(buffers: Int): TLOutwardNode =
TLBuffer.chain(buffers).foldRight(delayNode)(_ :*= _) :*= outwardNode
protected def fixedWidthTo(buffer: BufferParams): TLOutwardNode =
TLWidthWidget(beatBytes) :*= bufferTo(buffer)
protected def fragmentTo(buffer: BufferParams): TLOutwardNode =
TLFragmenter(beatBytes, blockBytes) :*= bufferTo(buffer)
protected def fragmentTo(minSize: Int, maxSize: Int, buffer: BufferParams): TLOutwardNode =
TLFragmenter(minSize, maxSize) :*= bufferTo(buffer)
protected def delayNode(implicit p: Parameters): TLNode = {
val delayProb = p(TLBusDelayProbability)
if (delayProb > 0.0) {
TLDelayer(delayProb) :*=* TLBuffer(BufferParams.flow) :*=* TLDelayer(delayProb)
} else {
val nodelay = TLIdentityNode()
nodelay
}
}
protected def to[T](name: String)(body: => T): T = {
this { LazyScope(s"coupler_to_${name}") { body } }
}
protected def from[T](name: String)(body: => T): T = {
this { LazyScope(s"coupler_from_${name}") { body } }
}
}
trait HasTLXbarPhy { this: TLBusWrapper =>
private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar")
protected def inwardNode: TLInwardNode = xbar.node
protected def outwardNode: TLOutwardNode = xbar.node
}
object TLIdentity {
def gen: TLNode = {
val passthru = TLIdentityNode()
passthru
}
}

View File

@ -30,18 +30,6 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle]): TLManagerPortParameters =
pu.copy(managers = pu.managers.map { m => m.copy (nodePath = node +: m.nodePath) })
override def getO(pu: TLManagerPortParameters): Option[BaseNode] = {
val head = pu.managers.map(_.nodePath.headOption)
if (head.exists(!_.isDefined) || head.map(_.get).distinct.size != 1) {
None
} else {
val subproblem = pu.copy(managers = pu.managers.map(m => m.copy(nodePath = m.nodePath.tail)))
getO(subproblem) match {
case Some(x) => Some(x)
case None => Some(head(0).get)
}
}
}
}
case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams)

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.amba.ahb._
import freechips.rocketchip.amba.apb._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.config._
import freechips.rocketchip.coreplex.{BaseCoreplexConfig}
import freechips.rocketchip.subsystem.{BaseSubsystemConfig}
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.tilelink._
@ -79,7 +79,7 @@ class WithTLXbarUnitTests extends Config((site, here, up) => {
Module(new TLMulticlientXbarTest(4,4, txns=2*txns, timeout=timeout)) ) }
})
class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)

View File

@ -108,7 +108,7 @@ trait GeneratorApp extends App with HasGeneratorUtilities {
/** Output software test Makefrags, which provide targets for integration testing. */
def generateTestSuiteMakefrags {
addTestSuites
writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Coreplex-specific test suites
writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites
}
def addTestSuites {

View File

@ -43,6 +43,28 @@ package object util {
def readAndHold(addr: UInt, enable: Bool): T = x.read(addr, enable) holdUnless RegNext(enable)
}
implicit class StringToAugmentedString(val x: String) extends AnyVal {
/** converts from camel case to to underscores, also removing all spaces */
def underscore: String = x.tail.foldLeft(x.headOption.map(_.toLower + "") getOrElse "") {
case (acc, c) if c.isUpper => acc + "_" + c.toLower
case (acc, c) if c == ' ' => acc
case (acc, c) => acc + c
}
/** converts spaces or underscores to hyphens, also lowering case */
def kebab: String = x.toLowerCase map {
case ' ' => '-'
case '_' => '-'
case c => c
}
def named(name: Option[String]): String = {
x + name.map("_named_" + _ ).getOrElse("_with_no_name")
}
def named(name: String): String = named(Some(name))
}
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
implicit def wcToUInt(c: WideCounter): UInt = c.value