subsystem: bus wrappers now in BaseSubsystem
This commit is contained in:
		@@ -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.subsystem.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))
 | 
			
		||||
 | 
			
		||||
  pbus.toVariableWidthSlave(Some("Debug")){ debug.node }
 | 
			
		||||
  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.subsystem._
 | 
			
		||||
import freechips.rocketchip.subsystem.{BaseSubsystem, HasResetVectorWire}
 | 
			
		||||
import freechips.rocketchip.diplomacy._
 | 
			
		||||
import freechips.rocketchip.tilelink._
 | 
			
		||||
import freechips.rocketchip.util._
 | 
			
		||||
@@ -59,7 +59,7 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Adds a boot ROM that contains the DTB describing the system's subsystem. */
 | 
			
		||||
trait HasPeripheryBootROM extends HasPeripheryBus {
 | 
			
		||||
trait HasPeripheryBootROM { this: BaseSubsystem =>
 | 
			
		||||
  val dtb: DTB
 | 
			
		||||
  private val params = p(BootROMParams)
 | 
			
		||||
  private lazy val contents = {
 | 
			
		||||
@@ -71,7 +71,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
 | 
			
		||||
 | 
			
		||||
  val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
 | 
			
		||||
 | 
			
		||||
  pbus.toVariableWidthSlave(Some("BootROM")){ bootrom.node }
 | 
			
		||||
  pbus.toVariableWidthSlave(Some("bootrom")){ bootrom.node }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Subsystem will power-on running at 0x10040 (BootROM) */
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ package freechips.rocketchip.devices.tilelink
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import freechips.rocketchip.config.{Field, Parameters}
 | 
			
		||||
import freechips.rocketchip.subsystem.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.subsystem.HasPeripheryBus
 | 
			
		||||
import freechips.rocketchip.subsystem.BaseSubsystem
 | 
			
		||||
import freechips.rocketchip.diplomacy._
 | 
			
		||||
import freechips.rocketchip.regmapper._
 | 
			
		||||
import freechips.rocketchip.tilelink._
 | 
			
		||||
@@ -91,7 +91,7 @@ class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Trait that will connect a CLINT to a subsystem */
 | 
			
		||||
trait HasPeripheryCLINT extends HasPeripheryBus {
 | 
			
		||||
trait HasPeripheryCLINT { this: BaseSubsystem =>
 | 
			
		||||
  val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes))
 | 
			
		||||
  pbus.toVariableWidthSlave(Some("CLINT")) { clint.node }
 | 
			
		||||
  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.subsystem.HasSystemBus
 | 
			
		||||
import freechips.rocketchip.subsystem.BaseSubsystem
 | 
			
		||||
import freechips.rocketchip.diplomacy._
 | 
			
		||||
import freechips.rocketchip.tilelink._
 | 
			
		||||
import freechips.rocketchip.util._
 | 
			
		||||
@@ -118,7 +118,7 @@ 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))
 | 
			
		||||
  sbus.toSlave(Some("Error")){ error.node }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,9 @@
 | 
			
		||||
package freechips.rocketchip.devices.tilelink
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import freechips.rocketchip.subsystem.{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,7 +13,7 @@ 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))
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ package freechips.rocketchip.devices.tilelink
 | 
			
		||||
import Chisel._
 | 
			
		||||
import Chisel.ImplicitConversions._
 | 
			
		||||
import freechips.rocketchip.config.{Field, Parameters}
 | 
			
		||||
import freechips.rocketchip.subsystem.{HasInterruptBus, HasPeripheryBus}
 | 
			
		||||
import freechips.rocketchip.subsystem.BaseSubsystem
 | 
			
		||||
import freechips.rocketchip.diplomacy._
 | 
			
		||||
import freechips.rocketchip.regmapper._
 | 
			
		||||
import freechips.rocketchip.tilelink._
 | 
			
		||||
@@ -269,8 +269,8 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Trait that will connect a PLIC to a subsystem */
 | 
			
		||||
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
 | 
			
		||||
  val plic  = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)))
 | 
			
		||||
  pbus.toVariableWidthSlave(Some("PLIC")) { plic.node }
 | 
			
		||||
trait HasPeripheryPLIC { this: BaseSubsystem =>
 | 
			
		||||
  val plic  = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
 | 
			
		||||
  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.subsystem.HasMemoryBus
 | 
			
		||||
import freechips.rocketchip.subsystem.BaseSubsystem
 | 
			
		||||
import freechips.rocketchip.diplomacy._
 | 
			
		||||
import freechips.rocketchip.tilelink._
 | 
			
		||||
 | 
			
		||||
@@ -46,20 +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(m => m.toVariableWidthSlave(Some("Zero"))(_))
 | 
			
		||||
                .zipWithIndex
 | 
			
		||||
                .map { case (attach, 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")))
 | 
			
		||||
    attach { zero.node }
 | 
			
		||||
    bus.toVariableWidthSlave(Some("Zero")) { zero.node }
 | 
			
		||||
    zero
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,7 @@ case object TileId extends Field[Int]
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
@@ -48,13 +47,13 @@ class GroundTestSubsystemModule[+L <: GroundTestSubsystem](_outer: L) extends Ba
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 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))
 | 
			
		||||
  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.fromOtherMaster(Some("Fuzzer")) { fuzzer.node }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,15 +26,53 @@ abstract class BareSubsystemModule[+L <: BareSubsystem](_outer: L) extends LazyM
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Base Subsystem class with no peripheral devices or ports added */
 | 
			
		||||
abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem
 | 
			
		||||
    with HasInterruptBus
 | 
			
		||||
    with HasSystemBus
 | 
			
		||||
    with HasPeripheryBus
 | 
			
		||||
    with HasMemoryBus {
 | 
			
		||||
abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem {
 | 
			
		||||
  override val module: BaseSubsystemModule[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
 | 
			
		||||
@@ -61,7 +99,7 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem
 | 
			
		||||
 | 
			
		||||
abstract class BaseSubsystemModule[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModule(_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)] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ class BaseSubsystemConfig 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")
 | 
			
		||||
@@ -156,7 +157,7 @@ class WithIncoherentTiles extends Config((site, here, up) => {
 | 
			
		||||
    r.copy(master = r.master.copy(cork = Some(true)))
 | 
			
		||||
  }
 | 
			
		||||
  case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { subsystem =>
 | 
			
		||||
    val ww = LazyModule(new TLWidthWidget(subsystem.sbusBeatBytes)(subsystem.p))
 | 
			
		||||
    val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)(subsystem.p))
 | 
			
		||||
    (ww.node, ww.node, () => None)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
@@ -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)
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -43,17 +43,3 @@ class FrontBus(params: FrontBusParams, val crossing: SubsystemClockCrossing = Sy
 | 
			
		||||
    to("sbus") { gen :=* TLBuffer(buffer) :=* outwardNode }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 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 =>
 | 
			
		||||
    fbus.toSystemBus() { sbus.fromFrontBus { fbus.crossTLOut } }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,12 +14,13 @@ class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
 | 
			
		||||
    with HasExternallyDrivenTileConstants
 | 
			
		||||
    with Clocked
 | 
			
		||||
 | 
			
		||||
trait HasTiles extends HasSystemBus {
 | 
			
		||||
trait HasTiles { this: BaseSubsystem =>
 | 
			
		||||
  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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,11 @@ case object BroadcastKey extends Field(BroadcastParams())
 | 
			
		||||
case class BankedL2Params(
 | 
			
		||||
  nMemoryChannels:  Int = 1,
 | 
			
		||||
  nBanksPerChannel: Int = 1,
 | 
			
		||||
  coherenceManager: HasMemoryBus => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { subsystem =>
 | 
			
		||||
  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.sbusBeatBytes))
 | 
			
		||||
    val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes))
 | 
			
		||||
    ww.node :*= bh.node
 | 
			
		||||
    (bh.node, ww.node, () => None)
 | 
			
		||||
  }) {
 | 
			
		||||
@@ -72,29 +72,3 @@ class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWr
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 => sbus.toMemoryBus { in } }
 | 
			
		||||
      mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out
 | 
			
		||||
    }
 | 
			
		||||
    mbus
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -107,16 +107,3 @@ class PeripheryBus(params: PeripheryBusParams, val crossing: SubsystemClockCross
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 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() { pbus.crossTLIn } }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,12 +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)
 | 
			
		||||
@@ -73,13 +74,14 @@ 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 portName = "mmio_port_axi4"
 | 
			
		||||
  private val device = new SimpleBus(portName.kebab, Nil)
 | 
			
		||||
@@ -119,7 +121,7 @@ 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(
 | 
			
		||||
@@ -160,7 +162,7 @@ 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 portName = "mmio_port_tl"
 | 
			
		||||
  private val device = new SimpleBus(portName.kebab, Nil)
 | 
			
		||||
@@ -204,7 +206,7 @@ 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(
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -31,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 HasPeripheryDebug { this: BaseSubsystem =>
 | 
			
		||||
  val module: HasRocketTilesModuleImp
 | 
			
		||||
 | 
			
		||||
  protected val rocketTileParams = p(RocketTilesKey)
 | 
			
		||||
@@ -104,7 +103,7 @@ trait HasRocketTiles extends HasTiles
 | 
			
		||||
          .map { BasicBusBlockerParams(_, pbus.beatBytes, sbus.beatBytes) }
 | 
			
		||||
          .map { bbbp => LazyModule(new BasicBusBlocker(bbbp)) }
 | 
			
		||||
          .map { bbb =>
 | 
			
		||||
            pbus.toVariableWidthSlave(Some("TileSlavePortBusBlocker")) { bbb.controlNode }
 | 
			
		||||
            pbus.toVariableWidthSlave(Some("bus_blocker")) { bbb.controlNode }
 | 
			
		||||
            rocket.crossTLIn :*= bbb.node
 | 
			
		||||
          } .getOrElse { rocket.crossTLIn }
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -96,15 +96,3 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user