Refactor Tile to use cake pattern (#502)
* [rocket] Refactor Tile into cake pattern with traits * [rocket] cacheDataBits &etc in HasCoreParameters * [rocket] pass TLEdgeOut implicitly rather than relying on val edge in HasCoreParameters * [rocket] frontend and icache now diplomatic * [rocket] file name capitalization * [rocket] re-add hook for inserting externally-defined Cores * [rocket] add FPUCoreIO * [groundtest] move TL1 Config instances to where they are used * [unittest] remove legacy unit tests * [groundtest] remove legacy device tests
This commit is contained in:
@ -4,16 +4,10 @@ package coreplex
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import junctions._
|
||||
import diplomacy._
|
||||
import uncore.tilelink._
|
||||
import rocket.{TileInterrupts, XLen}
|
||||
import uncore.tilelink2._
|
||||
import uncore.coherence._
|
||||
import uncore.agents._
|
||||
import uncore.devices._
|
||||
import uncore.util._
|
||||
import uncore.converters._
|
||||
import rocket._
|
||||
import util._
|
||||
|
||||
/** Widths of various points in the SoC */
|
||||
@ -56,102 +50,17 @@ trait HasCoreplexParameters {
|
||||
case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters
|
||||
|
||||
abstract class BareCoreplex(implicit p: Parameters) extends LazyModule
|
||||
|
||||
abstract class BareCoreplexBundle[+L <: BareCoreplex](_outer: L) extends GenericParameterizedBundle(_outer) {
|
||||
val outer = _outer
|
||||
implicit val p = outer.p
|
||||
}
|
||||
|
||||
abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) {
|
||||
val outer = _outer
|
||||
val io = _io ()
|
||||
}
|
||||
|
||||
trait CoreplexNetwork extends HasCoreplexParameters {
|
||||
val module: CoreplexNetworkModule
|
||||
|
||||
val l1tol2 = LazyModule(new TLXbar)
|
||||
val l1tol2_beatBytes = l1tol2Config.beatBytes
|
||||
val l1tol2_lineBytes = p(CacheBlockBytes)
|
||||
|
||||
val cbus = LazyModule(new TLXbar)
|
||||
val cbus_beatBytes = cbusConfig.beatBytes
|
||||
val cbus_lineBytes = l1tol2_lineBytes
|
||||
|
||||
val intBar = LazyModule(new IntXbar)
|
||||
|
||||
val mmio = TLOutputNode()
|
||||
val mmioInt = IntInputNode()
|
||||
|
||||
intBar.intnode := mmioInt
|
||||
|
||||
cbus.node :=
|
||||
TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata
|
||||
TLWidthWidget(l1tol2_beatBytes)(
|
||||
TLBuffer()(
|
||||
l1tol2.node)))
|
||||
|
||||
mmio :=
|
||||
TLBuffer()(
|
||||
TLWidthWidget(l1tol2_beatBytes)(
|
||||
l1tol2.node))
|
||||
}
|
||||
|
||||
trait CoreplexNetworkBundle extends HasCoreplexParameters {
|
||||
val outer: CoreplexNetwork
|
||||
|
||||
val mmio = outer.mmio.bundleOut
|
||||
val interrupts = outer.mmioInt.bundleIn
|
||||
}
|
||||
|
||||
trait CoreplexNetworkModule extends HasCoreplexParameters {
|
||||
val outer: CoreplexNetwork
|
||||
val io: CoreplexNetworkBundle
|
||||
|
||||
println("\nGenerated Address Map")
|
||||
for (manager <- outer.l1tol2.node.edgesIn(0).manager.managers) {
|
||||
val prot = (if (manager.supportsGet) "R" else "") +
|
||||
(if (manager.supportsPutFull) "W" else "") +
|
||||
(if (manager.executable) "X" else "") +
|
||||
(if (manager.supportsAcquire) " [C]" else "")
|
||||
manager.address.foreach { a =>
|
||||
println(f"\t${manager.name}%s ${a.base}%x - ${a.base+a.mask+1}%x, $prot")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagers extends CoreplexNetwork {
|
||||
val module: BankedL2CoherenceManagersModule
|
||||
|
||||
require (isPow2(l2Config.nBanksPerChannel))
|
||||
require (isPow2(l1tol2_lineBytes))
|
||||
|
||||
val mem = Seq.fill(l2Config.nMemoryChannels) {
|
||||
val bankBar = LazyModule(new TLXbar)
|
||||
val output = TLOutputNode()
|
||||
|
||||
output := bankBar.node
|
||||
val mask = ~BigInt((l2Config.nBanksPerChannel-1) * l1tol2_lineBytes)
|
||||
for (i <- 0 until l2Config.nBanksPerChannel) {
|
||||
val (in, out) = l2Config.coherenceManager(p)
|
||||
in := TLFilter(AddressSet(i * l1tol2_lineBytes, mask))(l1tol2.node)
|
||||
bankBar.node := out
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle {
|
||||
val outer: BankedL2CoherenceManagers
|
||||
|
||||
require (l2Config.nMemoryChannels <= 1, "Seq in Chisel Bundle needed to support > 1") // !!!
|
||||
val mem = outer.mem.map(_.bundleOut).toList.headOption // .headOption should be removed !!!
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule {
|
||||
val outer: BankedL2CoherenceManagers
|
||||
val io: BankedL2CoherenceManagersBundle
|
||||
}
|
||||
|
||||
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
||||
with CoreplexNetwork
|
||||
with BankedL2CoherenceManagers {
|
||||
|
56
src/main/scala/coreplex/BaseTile.scala
Normal file
56
src/main/scala/coreplex/BaseTile.scala
Normal file
@ -0,0 +1,56 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package coreplex
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import rocket.{TileInterrupts, XLen}
|
||||
import uncore.tilelink2._
|
||||
import util.GenericParameterizedBundle
|
||||
|
||||
abstract class BareTile(implicit p: Parameters) extends LazyModule
|
||||
|
||||
abstract class BareTileBundle[+L <: BareTile](_outer: L) extends GenericParameterizedBundle(_outer) {
|
||||
val outer = _outer
|
||||
implicit val p = outer.p
|
||||
}
|
||||
|
||||
abstract class BareTileModule[+L <: BareTile, +B <: BareTileBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) {
|
||||
val outer = _outer
|
||||
val io = _io ()
|
||||
}
|
||||
|
||||
// Uses a tile-internal crossbar to provide a single TileLink master port
|
||||
trait TileNetwork {
|
||||
implicit val p: Parameters
|
||||
val module: TileNetworkModule
|
||||
val l1backend = LazyModule(new TLXbar)
|
||||
val masterNodes = List(TLOutputNode())
|
||||
masterNodes.head := l1backend.node
|
||||
}
|
||||
|
||||
trait TileNetworkBundle {
|
||||
val outer: TileNetwork
|
||||
val master = outer.masterNodes.head.bundleOut
|
||||
}
|
||||
|
||||
trait TileNetworkModule {
|
||||
val outer: TileNetwork
|
||||
val io: TileNetworkBundle
|
||||
}
|
||||
|
||||
abstract class BaseTile(implicit p: Parameters) extends BareTile
|
||||
with TileNetwork {
|
||||
override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this))
|
||||
}
|
||||
|
||||
class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
||||
with TileNetworkBundle {
|
||||
val hartid = UInt(INPUT, p(XLen))
|
||||
val interrupts = new TileInterrupts()(p).asInput
|
||||
val resetVector = UInt(INPUT, p(XLen))
|
||||
}
|
||||
|
||||
class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io)
|
||||
with TileNetworkModule
|
@ -6,14 +6,10 @@ package coreplex
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import junctions.PAddrBits
|
||||
import rocket._
|
||||
import uncore.tilelink._
|
||||
import uncore.tilelink2._
|
||||
import uncore.coherence._
|
||||
import uncore.agents._
|
||||
import uncore.devices._
|
||||
import uncore.converters._
|
||||
import uncore.devices._
|
||||
import uncore.tilelink2._
|
||||
import uncore.util._
|
||||
import util._
|
||||
|
||||
@ -44,15 +40,8 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
|
||||
//L1DataCache
|
||||
case DCacheKey => DCacheConfig(nMSHRs = 2)
|
||||
case DataScratchpadSize => 0
|
||||
//L2 Memory System Params
|
||||
case AmoAluOperandBits => site(XLen)
|
||||
case NAcquireTransactors => 7
|
||||
case L2StoreDataQueueDepth => 1
|
||||
case L2DirectoryRepresentation => new NullRepresentation(site(NTiles))
|
||||
//Tile Constants
|
||||
case BuildRoCC => Nil
|
||||
case RoccNMemChannels => site(BuildRoCC).map(_.nMemChannels).foldLeft(0)(_ + _)
|
||||
case RoccNPTWPorts => site(BuildRoCC).map(_.nPTWPorts).foldLeft(0)(_ + _)
|
||||
//Rocket Core Constants
|
||||
case CoreInstBits => if (site(UseCompressed)) 16 else 32
|
||||
case FetchWidth => if (site(UseCompressed)) 2 else 1
|
||||
@ -76,37 +65,15 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
|
||||
case MtvecInit => Some(BigInt(0))
|
||||
case MtvecWritable => true
|
||||
//Uncore Paramters
|
||||
case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients
|
||||
case LNHeaderBits => log2Ceil(site(TLKey(site(TLId))).nManagers) +
|
||||
log2Up(site(TLKey(site(TLId))).nClients)
|
||||
case CBusConfig => TLBusConfig(beatBytes = site(XLen)/8)
|
||||
case L1toL2Config => TLBusConfig(beatBytes = site(XLen)/8) // increase for more PCIe bandwidth
|
||||
case TLKey("L1toL2") => {
|
||||
val useMEI = site(NTiles) <= 1
|
||||
TileLinkParameters(
|
||||
coherencePolicy = (
|
||||
if (useMEI) new MEICoherence(site(L2DirectoryRepresentation))
|
||||
else new MESICoherence(site(L2DirectoryRepresentation))),
|
||||
nManagers = site(BankedL2Config).nBanks + 1 /* MMIO */,
|
||||
nCachingClients = 1,
|
||||
nCachelessClients = 1,
|
||||
maxClientXacts = List(
|
||||
// L1 cache
|
||||
site(DCacheKey).nMSHRs + 1 /* IOMSHR */,
|
||||
// RoCC
|
||||
if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)).max,
|
||||
maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
|
||||
maxManagerXacts = site(NAcquireTransactors) + 2,
|
||||
dataBeats = (8 * site(CacheBlockBytes)) / site(XLen),
|
||||
dataBits = site(CacheBlockBytes)*8)
|
||||
}
|
||||
case BootROMFile => "./bootrom/bootrom.img"
|
||||
case NTiles => 1
|
||||
case NTiles => site(RocketConfigs).size
|
||||
case RocketConfigs => List(RocketConfig(site(XLen)))
|
||||
case BuildCore => (c: RocketConfig, p: Parameters) => new Rocket(c)(p)
|
||||
case BroadcastConfig => BroadcastConfig()
|
||||
case BankedL2Config => BankedL2Config()
|
||||
case CacheBlockBytes => 64
|
||||
case CacheBlockOffsetBits => log2Up(site(CacheBlockBytes))
|
||||
case EnableL2Logging => false
|
||||
})
|
||||
|
||||
class WithNCores(n: Int) extends Config((site, here, up) => {
|
||||
@ -185,7 +152,7 @@ class WithStatelessBridge extends Config((site, here, up) => {
|
||||
case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
|
||||
})
|
||||
|
||||
class WithL2Capacity(size_kb: Int) extends Config(Parameters.empty)
|
||||
class WithL2Capacity(size_kb: Int) extends Config(Parameters.empty) // TODO
|
||||
|
||||
class WithNL2Ways(n: Int) extends Config((site, here, up) => {
|
||||
case CacheName("L2") => up(CacheName("L2"), site).copy(nWays = n)
|
||||
@ -205,7 +172,6 @@ class WithSmallCores extends Config((site, here, up) => {
|
||||
case FPUKey => None
|
||||
case UseVM => false
|
||||
case BtbKey => BtbParameters(nEntries = 0)
|
||||
case NAcquireTransactors => 2
|
||||
case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4)
|
||||
case CacheName("L1I") => up(CacheName("L1I"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4)
|
||||
case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
|
||||
|
@ -4,69 +4,43 @@ package coreplex
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import junctions._
|
||||
import diplomacy._
|
||||
import uncore.tilelink._
|
||||
import uncore.tilelink2._
|
||||
import uncore.util._
|
||||
import util._
|
||||
import rocket._
|
||||
|
||||
/////
|
||||
|
||||
trait L2MasterPort extends CoreplexNetwork
|
||||
{
|
||||
val module: L2MasterPortModule
|
||||
val l2in = TLInputNode()
|
||||
l1tol2.node := l2in
|
||||
}
|
||||
|
||||
trait L2MasterPortBundle extends CoreplexNetworkBundle
|
||||
{
|
||||
val outer: L2MasterPort
|
||||
val l2in = outer.l2in.bundleIn
|
||||
}
|
||||
|
||||
trait L2MasterPortModule extends CoreplexNetworkModule
|
||||
{
|
||||
val outer: L2MasterPort
|
||||
val io: L2MasterPortBundle
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex
|
||||
with CoreplexRISCVPlatform
|
||||
with L2MasterPort
|
||||
with RocketTiles {
|
||||
with HasL2MasterPort
|
||||
with HasSynchronousRocketTiles {
|
||||
override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this))
|
||||
}
|
||||
|
||||
class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer)
|
||||
with CoreplexRISCVPlatformBundle
|
||||
with L2MasterPortBundle
|
||||
with RocketTilesBundle
|
||||
with HasL2MasterPortBundle
|
||||
with HasSynchronousRocketTilesBundle
|
||||
|
||||
class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
|
||||
with CoreplexRISCVPlatformModule
|
||||
with L2MasterPortModule
|
||||
with RocketTilesModule
|
||||
with HasL2MasterPortModule
|
||||
with HasSynchronousRocketTilesModule
|
||||
|
||||
/////
|
||||
|
||||
class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex
|
||||
with CoreplexRISCVPlatform
|
||||
with L2MasterPort
|
||||
with AsyncRocketTiles {
|
||||
with HasL2MasterPort
|
||||
with HasAsynchronousRocketTiles {
|
||||
override lazy val module = new MultiClockCoreplexModule(this, () => new MultiClockCoreplexBundle(this))
|
||||
}
|
||||
|
||||
class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](_outer: L) extends BaseCoreplexBundle(_outer)
|
||||
with CoreplexRISCVPlatformBundle
|
||||
with L2MasterPortBundle
|
||||
with AsyncRocketTilesBundle
|
||||
with HasL2MasterPortBundle
|
||||
with HasAsynchronousRocketTilesBundle
|
||||
|
||||
class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
|
||||
with CoreplexRISCVPlatformModule
|
||||
with L2MasterPortModule
|
||||
with AsyncRocketTilesModule
|
||||
with HasL2MasterPortModule
|
||||
with HasAsynchronousRocketTilesModule
|
||||
|
117
src/main/scala/coreplex/CoreplexNetwork.scala
Normal file
117
src/main/scala/coreplex/CoreplexNetwork.scala
Normal file
@ -0,0 +1,117 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package coreplex
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import uncore.tilelink2._
|
||||
import uncore.util._
|
||||
import util._
|
||||
|
||||
trait CoreplexNetwork extends HasCoreplexParameters {
|
||||
val module: CoreplexNetworkModule
|
||||
|
||||
val l1tol2 = LazyModule(new TLXbar)
|
||||
val l1tol2_beatBytes = l1tol2Config.beatBytes
|
||||
val l1tol2_lineBytes = p(CacheBlockBytes)
|
||||
|
||||
val cbus = LazyModule(new TLXbar)
|
||||
val cbus_beatBytes = cbusConfig.beatBytes
|
||||
val cbus_lineBytes = l1tol2_lineBytes
|
||||
|
||||
val intBar = LazyModule(new IntXbar)
|
||||
|
||||
val mmio = TLOutputNode()
|
||||
val mmioInt = IntInputNode()
|
||||
|
||||
intBar.intnode := mmioInt
|
||||
|
||||
cbus.node :=
|
||||
TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata
|
||||
TLWidthWidget(l1tol2_beatBytes)(
|
||||
TLBuffer()(
|
||||
l1tol2.node)))
|
||||
|
||||
mmio :=
|
||||
TLBuffer()(
|
||||
TLWidthWidget(l1tol2_beatBytes)(
|
||||
l1tol2.node))
|
||||
}
|
||||
|
||||
trait CoreplexNetworkBundle extends HasCoreplexParameters {
|
||||
val outer: CoreplexNetwork
|
||||
|
||||
val mmio = outer.mmio.bundleOut
|
||||
val interrupts = outer.mmioInt.bundleIn
|
||||
}
|
||||
|
||||
trait CoreplexNetworkModule extends HasCoreplexParameters {
|
||||
val outer: CoreplexNetwork
|
||||
val io: CoreplexNetworkBundle
|
||||
|
||||
println("\nGenerated Address Map")
|
||||
for (manager <- outer.l1tol2.node.edgesIn(0).manager.managers) {
|
||||
val prot = (if (manager.supportsGet) "R" else "") +
|
||||
(if (manager.supportsPutFull) "W" else "") +
|
||||
(if (manager.executable) "X" else "") +
|
||||
(if (manager.supportsAcquire) " [C]" else "")
|
||||
manager.address.foreach { a =>
|
||||
println(f"\t${manager.name}%s ${a.base}%x - ${a.base+a.mask+1}%x, $prot")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
trait BankedL2CoherenceManagers extends CoreplexNetwork {
|
||||
val module: BankedL2CoherenceManagersModule
|
||||
|
||||
require (isPow2(l2Config.nBanksPerChannel))
|
||||
require (isPow2(l1tol2_lineBytes))
|
||||
|
||||
val mem = Seq.fill(l2Config.nMemoryChannels) {
|
||||
val bankBar = LazyModule(new TLXbar)
|
||||
val output = TLOutputNode()
|
||||
|
||||
output := bankBar.node
|
||||
val mask = ~BigInt((l2Config.nBanksPerChannel-1) * l1tol2_lineBytes)
|
||||
for (i <- 0 until l2Config.nBanksPerChannel) {
|
||||
val (in, out) = l2Config.coherenceManager(p)
|
||||
in := TLFilter(AddressSet(i * l1tol2_lineBytes, mask))(l1tol2.node)
|
||||
bankBar.node := out
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle {
|
||||
val outer: BankedL2CoherenceManagers
|
||||
|
||||
require (l2Config.nMemoryChannels <= 1, "Seq in Chisel Bundle needed to support > 1") // !!!
|
||||
val mem = outer.mem.map(_.bundleOut).toList.headOption // .headOption should be removed !!!
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule {
|
||||
val outer: BankedL2CoherenceManagers
|
||||
val io: BankedL2CoherenceManagersBundle
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
trait HasL2MasterPort extends CoreplexNetwork {
|
||||
val module: HasL2MasterPortModule
|
||||
val l2in = TLInputNode()
|
||||
l1tol2.node := l2in
|
||||
}
|
||||
|
||||
trait HasL2MasterPortBundle extends CoreplexNetworkBundle {
|
||||
val outer: HasL2MasterPort
|
||||
val l2in = outer.l2in.bundleIn
|
||||
}
|
||||
|
||||
trait HasL2MasterPortModule extends CoreplexNetworkModule {
|
||||
val outer: HasL2MasterPort
|
||||
val io: HasL2MasterPortBundle
|
||||
}
|
@ -5,86 +5,67 @@ package coreplex
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import uncore.tilelink2._
|
||||
import uncore.coherence._
|
||||
import rocket._
|
||||
import uncore.devices.NTiles
|
||||
import uncore.tilelink2._
|
||||
|
||||
trait RocketTiles extends CoreplexRISCVPlatform {
|
||||
val module: RocketTilesModule
|
||||
case object RocketConfigs extends Field[Seq[RocketConfig]]
|
||||
|
||||
val rocketTiles = List.tabulate(p(NTiles)) { i => LazyModule(new RocketTile(i)) }
|
||||
val tileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
||||
trait HasSynchronousRocketTiles extends CoreplexRISCVPlatform {
|
||||
val module: HasSynchronousRocketTilesModule
|
||||
|
||||
val rocketTiles: Seq[RocketTile] = p(RocketConfigs).map { c =>
|
||||
LazyModule(new RocketTile(c)(p.alterPartial {
|
||||
case SharedMemoryTLEdge => l1tol2.node.edgesIn(0)
|
||||
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
|
||||
}))}
|
||||
|
||||
tileIntNodes.foreach { _ := plic.intnode }
|
||||
rocketTiles.foreach { r =>
|
||||
r.masterNodes.foreach { l1tol2.node := _ }
|
||||
r.slaveNode.foreach { _ := cbus.node }
|
||||
l1tol2.node := r.cachedOut
|
||||
l1tol2.node := r.uncachedOut
|
||||
}
|
||||
|
||||
val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
||||
rocketTileIntNodes.foreach { _ := plic.intnode }
|
||||
}
|
||||
|
||||
trait RocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
val outer: RocketTiles
|
||||
trait HasSynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
val outer: HasSynchronousRocketTiles
|
||||
}
|
||||
|
||||
trait RocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||
val outer: RocketTiles
|
||||
val io: RocketTilesBundle
|
||||
trait HasSynchronousRocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||
val outer: HasSynchronousRocketTiles
|
||||
val io: HasSynchronousRocketTilesBundle
|
||||
|
||||
outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) =>
|
||||
tile.io.hartid := UInt(i)
|
||||
tile.io.resetVector := io.resetVector
|
||||
tile.io.interrupts := outer.clint.module.io.tiles(i)
|
||||
tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i)
|
||||
tile.io.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0)
|
||||
tile.io.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1))
|
||||
tile.io.interrupts.meip := outer.rocketTileIntNodes(i).bundleOut(0)(0)
|
||||
tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1))
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncRocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule {
|
||||
val rocket = LazyModule(new RocketTile(tileId))
|
||||
trait HasAsynchronousRocketTiles extends CoreplexRISCVPlatform {
|
||||
val module: HasAsynchronousRocketTilesModule
|
||||
|
||||
val cachedOut = TLAsyncOutputNode()
|
||||
val uncachedOut = TLAsyncOutputNode()
|
||||
val slaveNode = rocket.slaveNode.map(_ => TLAsyncInputNode())
|
||||
val rocketTiles: Seq[AsyncRocketTile] = p(RocketConfigs).map { c =>
|
||||
LazyModule(new AsyncRocketTile(c)(p.alterPartial {
|
||||
case SharedMemoryTLEdge => l1tol2.node.edgesIn(0)
|
||||
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
|
||||
}))}
|
||||
|
||||
cachedOut := TLAsyncCrossingSource()(rocket.cachedOut)
|
||||
uncachedOut := TLAsyncCrossingSource()(rocket.uncachedOut)
|
||||
(rocket.slaveNode zip slaveNode) foreach { case (r,n) => r := TLAsyncCrossingSink()(n) }
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
val cached = cachedOut.bundleOut
|
||||
val uncached = uncachedOut.bundleOut
|
||||
val slave = slaveNode.map(_.bundleIn)
|
||||
val hartid = UInt(INPUT, p(XLen))
|
||||
val interrupts = new TileInterrupts()(rocket.coreParams).asInput
|
||||
val resetVector = UInt(INPUT, p(XLen))
|
||||
}
|
||||
rocket.module.io.interrupts := ShiftRegister(io.interrupts, 3)
|
||||
// signals that do not change:
|
||||
rocket.module.io.hartid := io.hartid
|
||||
rocket.module.io.resetVector := io.resetVector
|
||||
}
|
||||
}
|
||||
|
||||
trait AsyncRocketTiles extends CoreplexRISCVPlatform {
|
||||
val module: AsyncRocketTilesModule
|
||||
|
||||
val rocketTiles = List.tabulate(p(NTiles)) { i => LazyModule(new AsyncRocketTile(i)) }
|
||||
val tileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
||||
|
||||
tileIntNodes.foreach { _ := plic.intnode }
|
||||
rocketTiles.foreach { r =>
|
||||
r.masterNodes.foreach { l1tol2.node := TLAsyncCrossingSink()(_) }
|
||||
r.slaveNode.foreach { _ := TLAsyncCrossingSource()(cbus.node) }
|
||||
l1tol2.node := TLAsyncCrossingSink()(r.cachedOut)
|
||||
l1tol2.node := TLAsyncCrossingSink()(r.uncachedOut)
|
||||
}
|
||||
|
||||
val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
||||
rocketTileIntNodes.foreach { _ := plic.intnode }
|
||||
}
|
||||
|
||||
trait AsyncRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
val outer: AsyncRocketTiles
|
||||
trait HasAsynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
val outer: HasAsynchronousRocketTiles
|
||||
|
||||
val tcrs = Vec(nTiles, new Bundle {
|
||||
val clock = Clock(INPUT)
|
||||
@ -92,9 +73,9 @@ trait AsyncRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
})
|
||||
}
|
||||
|
||||
trait AsyncRocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||
val outer: AsyncRocketTiles
|
||||
val io: AsyncRocketTilesBundle
|
||||
trait HasAsynchronousRocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||
val outer: HasAsynchronousRocketTiles
|
||||
val io: HasAsynchronousRocketTilesBundle
|
||||
|
||||
outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) =>
|
||||
tile.clock := io.tcrs(i).clock
|
||||
@ -103,7 +84,7 @@ trait AsyncRocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||
tile.io.resetVector := io.resetVector
|
||||
tile.io.interrupts := outer.clint.module.io.tiles(i)
|
||||
tile.io.interrupts.debug := outer.debug.module.io.debugInterrupts(i)
|
||||
tile.io.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0)
|
||||
tile.io.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1))
|
||||
tile.io.interrupts.meip := outer.rocketTileIntNodes(i).bundleOut(0)(0)
|
||||
tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user