coreplex: support rational crossing to L2 (#534)
This commit is contained in:
parent
61fbe62112
commit
03f2fe02ac
@ -18,6 +18,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
|
|||||||
case PAddrBits => 32
|
case PAddrBits => 32
|
||||||
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
|
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
|
||||||
case ASIdBits => 7
|
case ASIdBits => 7
|
||||||
|
case RocketCrossing => Synchronous
|
||||||
//Params used by all caches
|
//Params used by all caches
|
||||||
case CacheName("L1I") => CacheConfig(
|
case CacheName("L1I") => CacheConfig(
|
||||||
nSets = 64,
|
nSets = 64,
|
||||||
@ -215,3 +216,15 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => {
|
|||||||
class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
|
class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
|
||||||
case BootROMFile => bootROMFile
|
case BootROMFile => bootROMFile
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithSynchronousRocketTiles extends Config((site, here, up) => {
|
||||||
|
case RocketCrossing => Synchronous
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithAynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => {
|
||||||
|
case RocketCrossing => Asynchronous(depth, sync)
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithRationalRocketTiles extends Config((site, here, up) => {
|
||||||
|
case RocketCrossing => Rational
|
||||||
|
})
|
||||||
|
@ -12,35 +12,16 @@ import util._
|
|||||||
class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex
|
class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex
|
||||||
with CoreplexRISCVPlatform
|
with CoreplexRISCVPlatform
|
||||||
with HasL2MasterPort
|
with HasL2MasterPort
|
||||||
with HasSynchronousRocketTiles {
|
with HasRocketTiles {
|
||||||
override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this))
|
override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer)
|
class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer)
|
||||||
with CoreplexRISCVPlatformBundle
|
with CoreplexRISCVPlatformBundle
|
||||||
with HasL2MasterPortBundle
|
with HasL2MasterPortBundle
|
||||||
with HasSynchronousRocketTilesBundle
|
with HasRocketTilesBundle
|
||||||
|
|
||||||
class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
|
class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
|
||||||
with CoreplexRISCVPlatformModule
|
with CoreplexRISCVPlatformModule
|
||||||
with HasL2MasterPortModule
|
with HasL2MasterPortModule
|
||||||
with HasSynchronousRocketTilesModule
|
with HasRocketTilesModule
|
||||||
|
|
||||||
/////
|
|
||||||
|
|
||||||
class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|
||||||
with CoreplexRISCVPlatform
|
|
||||||
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 HasL2MasterPortBundle
|
|
||||||
with HasAsynchronousRocketTilesBundle
|
|
||||||
|
|
||||||
class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io)
|
|
||||||
with CoreplexRISCVPlatformModule
|
|
||||||
with HasL2MasterPortModule
|
|
||||||
with HasAsynchronousRocketTilesModule
|
|
||||||
|
@ -8,84 +8,85 @@ import diplomacy._
|
|||||||
import rocket._
|
import rocket._
|
||||||
import uncore.tilelink2._
|
import uncore.tilelink2._
|
||||||
|
|
||||||
|
sealed trait ClockCrossing
|
||||||
|
case object Synchronous extends ClockCrossing
|
||||||
|
case object Rational extends ClockCrossing
|
||||||
|
case class Asynchronous(depth: Int, sync: Int = 2) extends ClockCrossing
|
||||||
|
|
||||||
case object RocketConfigs extends Field[Seq[RocketConfig]]
|
case object RocketConfigs extends Field[Seq[RocketConfig]]
|
||||||
|
case object RocketCrossing extends Field[ClockCrossing]
|
||||||
|
|
||||||
trait HasSynchronousRocketTiles extends CoreplexRISCVPlatform {
|
trait HasRocketTiles extends CoreplexRISCVPlatform {
|
||||||
val module: HasSynchronousRocketTilesModule
|
val module: HasRocketTilesModule
|
||||||
|
|
||||||
val rocketTiles: Seq[RocketTile] = p(RocketConfigs).map { c =>
|
private val crossing = p(RocketCrossing)
|
||||||
LazyModule(new RocketTile(c)(p.alterPartial {
|
private val configs = p(RocketConfigs)
|
||||||
|
private val pWithExtra = p.alterPartial {
|
||||||
case SharedMemoryTLEdge => l1tol2.node.edgesIn(0)
|
case SharedMemoryTLEdge => l1tol2.node.edgesIn(0)
|
||||||
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
|
case PAddrBits => l1tol2.node.edgesIn(0).bundle.addressBits
|
||||||
}))}
|
|
||||||
|
|
||||||
rocketTiles.foreach { r =>
|
|
||||||
r.masterNodes.foreach { l1tol2.node := TLBuffer()(_) }
|
|
||||||
r.slaveNode.foreach { _ := cbus.node }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
private val rocketTileIntNodes = configs.map { _ => IntInternalOutputNode() }
|
||||||
rocketTileIntNodes.foreach { _ := plic.intnode }
|
rocketTileIntNodes.foreach { _ := plic.intnode }
|
||||||
|
|
||||||
|
private def wireInterrupts(x: TileInterrupts, i: Int) {
|
||||||
|
x := clint.module.io.tiles(i)
|
||||||
|
x.debug := debug.module.io.debugInterrupts(i)
|
||||||
|
x.meip := rocketTileIntNodes(i).bundleOut(0)(0)
|
||||||
|
x.seip.foreach { _ := rocketTileIntNodes(i).bundleOut(0)(1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasSynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) =>
|
||||||
val outer: HasSynchronousRocketTiles
|
crossing match {
|
||||||
|
case Synchronous => {
|
||||||
|
val tile = LazyModule(new RocketTile(c)(pWithExtra))
|
||||||
|
tile.masterNodes.foreach { l1tol2.node := TLBuffer()(_) }
|
||||||
|
tile.slaveNode.foreach { _ := cbus.node }
|
||||||
|
(io: HasRocketTilesBundle) => {
|
||||||
|
// leave clock as default (simpler for hierarchical PnR)
|
||||||
|
tile.module.io.hartid := UInt(i)
|
||||||
|
tile.module.io.resetVector := io.resetVector
|
||||||
|
wireInterrupts(tile.module.io.interrupts, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Asynchronous(depth, sync) => {
|
||||||
|
val wrapper = LazyModule(new AsyncRocketTile(c)(pWithExtra))
|
||||||
|
wrapper.masterNodes.foreach { l1tol2.node := TLAsyncCrossingSink(depth, sync)(_) }
|
||||||
|
wrapper.slaveNode.foreach { _ := TLAsyncCrossingSource(sync)(cbus.node) }
|
||||||
|
(io: HasRocketTilesBundle) => {
|
||||||
|
wrapper.module.clock := io.tcrs(i).clock
|
||||||
|
wrapper.module.reset := io.tcrs(i).reset
|
||||||
|
wrapper.module.io.hartid := UInt(i)
|
||||||
|
wrapper.module.io.resetVector := io.resetVector
|
||||||
|
wireInterrupts(wrapper.module.io.interrupts, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Rational => {
|
||||||
|
val wrapper = LazyModule(new RationalRocketTile(c)(pWithExtra))
|
||||||
|
wrapper.masterNodes.foreach { l1tol2.node := TLRationalCrossingSink()(_) }
|
||||||
|
wrapper.slaveNode.foreach { _ := TLRationalCrossingSource()(cbus.node) }
|
||||||
|
(io: HasRocketTilesBundle) => {
|
||||||
|
wrapper.module.clock := io.tcrs(i).clock
|
||||||
|
wrapper.module.reset := io.tcrs(i).reset
|
||||||
|
wrapper.module.io.hartid := UInt(i)
|
||||||
|
wrapper.module.io.resetVector := io.resetVector
|
||||||
|
wireInterrupts(wrapper.module.io.interrupts, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.rocketTileIntNodes(i).bundleOut(0)(0)
|
|
||||||
tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasAsynchronousRocketTiles extends CoreplexRISCVPlatform {
|
trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||||
val module: HasAsynchronousRocketTilesModule
|
val outer: HasRocketTiles
|
||||||
|
val tcrs = Vec(p(RocketConfigs).size, new Bundle {
|
||||||
import rocket.AsyncRocketTile
|
|
||||||
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
|
|
||||||
}))}
|
|
||||||
|
|
||||||
rocketTiles.foreach { r =>
|
|
||||||
r.masterNodes.foreach { l1tol2.node := TLAsyncCrossingSink()(_) }
|
|
||||||
r.slaveNode.foreach { _ := TLAsyncCrossingSource()(cbus.node) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val rocketTileIntNodes = rocketTiles.map { _ => IntInternalOutputNode() }
|
|
||||||
rocketTileIntNodes.foreach { _ := plic.intnode }
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasAsynchronousRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
|
||||||
val outer: HasAsynchronousRocketTiles
|
|
||||||
|
|
||||||
val tcrs = Vec(nTiles, new Bundle {
|
|
||||||
val clock = Clock(INPUT)
|
val clock = Clock(INPUT)
|
||||||
val reset = Bool(INPUT)
|
val reset = Bool(INPUT)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasAsynchronousRocketTilesModule extends CoreplexRISCVPlatformModule {
|
trait HasRocketTilesModule extends CoreplexRISCVPlatformModule {
|
||||||
val outer: HasAsynchronousRocketTiles
|
val outer: HasRocketTiles
|
||||||
val io: HasAsynchronousRocketTilesBundle
|
val io: HasRocketTilesBundle
|
||||||
|
outer.rocketWires.foreach { _(io) }
|
||||||
outer.rocketTiles.map(_.module).zipWithIndex.foreach { case (tile, i) =>
|
|
||||||
tile.clock := io.tcrs(i).clock
|
|
||||||
tile.reset := io.tcrs(i).reset
|
|
||||||
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.rocketTileIntNodes(i).bundleOut(0)(0)
|
|
||||||
tile.io.interrupts.seip.foreach(_ := outer.rocketTileIntNodes(i).bundleOut(0)(1))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -73,3 +73,27 @@ class AsyncRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModul
|
|||||||
rocket.module.io.resetVector := io.resetVector
|
rocket.module.io.resetVector := io.resetVector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RationalRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModule {
|
||||||
|
val rocket = LazyModule(new RocketTile(c))
|
||||||
|
|
||||||
|
val masterNodes = rocket.masterNodes.map(_ => TLRationalOutputNode())
|
||||||
|
val slaveNode = rocket.slaveNode.map(_ => TLRationalInputNode())
|
||||||
|
|
||||||
|
(rocket.masterNodes zip masterNodes) foreach { case (r,n) => n := TLRationalCrossingSource()(r) }
|
||||||
|
(rocket.slaveNode zip slaveNode) foreach { case (r,n) => r := TLRationalCrossingSink()(n) }
|
||||||
|
|
||||||
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
val io = new Bundle {
|
||||||
|
val master = masterNodes.head.bundleOut // TODO fix after Chisel #366
|
||||||
|
val slave = slaveNode.map(_.bundleIn)
|
||||||
|
val hartid = UInt(INPUT, p(XLen))
|
||||||
|
val interrupts = new TileInterrupts()(p).asInput
|
||||||
|
val resetVector = UInt(INPUT, p(XLen))
|
||||||
|
}
|
||||||
|
rocket.module.io.interrupts := ShiftRegister(io.interrupts, 1)
|
||||||
|
// signals that do not change:
|
||||||
|
rocket.module.io.hartid := io.hartid
|
||||||
|
rocket.module.io.resetVector := io.resetVector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -29,4 +29,11 @@ trait RocketPlexMasterBundle extends L2CrossbarBundle {
|
|||||||
trait RocketPlexMasterModule extends L2CrossbarModule {
|
trait RocketPlexMasterModule extends L2CrossbarModule {
|
||||||
val outer: RocketPlexMaster
|
val outer: RocketPlexMaster
|
||||||
val io: RocketPlexMasterBundle
|
val io: RocketPlexMasterBundle
|
||||||
|
val clock: Clock
|
||||||
|
val reset: Bool
|
||||||
|
|
||||||
|
outer.coreplex.module.io.tcrs.foreach { case tcr =>
|
||||||
|
tcr.clock := clock
|
||||||
|
tcr.reset := reset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user