Merge pull request #1190 from freechipsproject/bus-api
BusWrapper API Update
This commit is contained in:
		@@ -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
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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()
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
}
 | 
			
		||||
@@ -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 }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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) }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 =>
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
}
 | 
			
		||||
@@ -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()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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)] = {
 | 
			
		||||
@@ -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)
 | 
			
		||||
})
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										50
									
								
								src/main/scala/subsystem/FrontBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/main/scala/subsystem/FrontBus.scala
									
									
									
									
									
										Normal 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 }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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 {
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
							
								
								
									
										77
									
								
								src/main/scala/subsystem/MemoryBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/main/scala/subsystem/MemoryBus.scala
									
									
									
									
									
										Normal 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) }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								src/main/scala/subsystem/PeripheryBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/main/scala/subsystem/PeripheryBus.scala
									
									
									
									
									
										Normal 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)
 | 
			
		||||
    }}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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 */
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
// See LICENSE.SiFive for license details.
 | 
			
		||||
 | 
			
		||||
package freechips.rocketchip.coreplex
 | 
			
		||||
package freechips.rocketchip.subsystem
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										109
									
								
								src/main/scala/subsystem/SystemBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/main/scala/subsystem/SystemBus.scala
									
									
									
									
									
										Normal 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 }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
 
 | 
			
		||||
@@ -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] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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._
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								src/main/scala/tilelink/BusWrapper.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/main/scala/tilelink/BusWrapper.scala
									
									
									
									
									
										Normal 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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user