tile: removed RocketTileWrapper. RocketTile now HasCrossing.
This commit is contained in:
parent
1cd018546c
commit
1579ddb97e
@ -77,27 +77,59 @@ trait HasRocketTiles extends HasTiles
|
|||||||
}
|
}
|
||||||
private val crossingTuples = rocketTileParams.zip(crossings)
|
private val crossingTuples = rocketTileParams.zip(crossings)
|
||||||
|
|
||||||
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
// Make a tile and wire its nodes into the system,
|
||||||
// according to the specified type of clock crossing.
|
// according to the specified type of clock crossing.
|
||||||
|
// Note that we also inject new nodes into the tile itself,
|
||||||
|
// also based on the crossing type.
|
||||||
val rocketTiles = crossingTuples.map { case (tp, crossing) =>
|
val rocketTiles = crossingTuples.map { case (tp, crossing) =>
|
||||||
// For legacy reasons, it is convenient to store some state
|
// For legacy reasons, it is convenient to store some state
|
||||||
// in the global Parameters about the specific tile being built now
|
// in the global Parameters about the specific tile being built now
|
||||||
val wrapper = LazyModule(new RocketTileWrapper(
|
val rocket = LazyModule(new RocketTile(tp, crossing.crossingType)(p.alterPartial {
|
||||||
params = tp,
|
|
||||||
crossing = crossing.crossingType
|
|
||||||
)(p.alterPartial {
|
|
||||||
case TileKey => tp
|
case TileKey => tp
|
||||||
case BuildRoCC => tp.rocc
|
case BuildRoCC => tp.rocc
|
||||||
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
||||||
case RocketCrossingKey => List(crossing)
|
|
||||||
})
|
})
|
||||||
).suggestName(tp.name)
|
).suggestName(tp.name)
|
||||||
|
|
||||||
// Connect the master ports of the tile to the system bus
|
// Connect the master ports of the tile to the system bus
|
||||||
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(wrapper.crossTLOut :=* wrapper.masterNode) }
|
|
||||||
|
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)))
|
||||||
|
crossing.crossingType match {
|
||||||
|
case _: AsynchronousCrossing => rocket.masterNode
|
||||||
|
case SynchronousCrossing(b) =>
|
||||||
|
require (!tp.boundaryBuffers || (b.depth >= 1 && !b.flow && !b.pipe), "Buffer misconfiguration creates feed-through paths")
|
||||||
|
rocket.masterNode
|
||||||
|
case RationalCrossing(dir) =>
|
||||||
|
require (dir != SlowToFast, "Misconfiguration? Core slower than fabric")
|
||||||
|
if (tp.boundaryBuffers) {
|
||||||
|
masterBuffer.node :=* rocket.masterNode
|
||||||
|
} else {
|
||||||
|
rocket.masterNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) }
|
||||||
|
|
||||||
// Connect the slave ports of the tile to the periphery bus
|
// Connect the slave ports of the tile to the periphery bus
|
||||||
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(wrapper.slaveNode :*= wrapper.crossTLIn) }
|
|
||||||
|
def tileSlaveBuffering: TLInwardNode = rocket {
|
||||||
|
val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
|
||||||
|
crossing.crossingType match {
|
||||||
|
case _: SynchronousCrossing => rocket.slaveNode // requirement already checked
|
||||||
|
case _: AsynchronousCrossing => rocket.slaveNode
|
||||||
|
case _: RationalCrossing =>
|
||||||
|
if (tp.boundaryBuffers) {
|
||||||
|
DisableMonitors { implicit p => rocket.slaveNode :*= slaveBuffer.node }
|
||||||
|
} else {
|
||||||
|
rocket.slaveNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(tileSlaveBuffering :*= rocket.crossTLIn) }
|
||||||
|
|
||||||
// Handle all the different types of interrupts crossing to or from the tile:
|
// Handle all the different types of interrupts crossing to or from the tile:
|
||||||
// 1. Debug interrupt is definitely asynchronous in all cases.
|
// 1. Debug interrupt is definitely asynchronous in all cases.
|
||||||
@ -110,10 +142,10 @@ trait HasRocketTiles extends HasTiles
|
|||||||
// are decoded from rocket.intNode inside the tile.
|
// are decoded from rocket.intNode inside the tile.
|
||||||
|
|
||||||
// 1. always async crossing for debug
|
// 1. always async crossing for debug
|
||||||
wrapper.intInwardNode := wrapper { IntSyncCrossingSink(3) } := debug.intnode
|
rocket.intInwardNode := rocket { IntSyncCrossingSink(3) } := debug.intnode
|
||||||
|
|
||||||
// 2. clint+plic conditionally crossing
|
// 2. clint+plic conditionally crossing
|
||||||
val periphIntNode = wrapper.intInwardNode :=* wrapper.crossIntIn
|
val periphIntNode = rocket.intInwardNode :=* rocket.crossIntIn
|
||||||
periphIntNode := clint.intnode // msip+mtip
|
periphIntNode := clint.intnode // msip+mtip
|
||||||
periphIntNode := plic.intnode // meip
|
periphIntNode := plic.intnode // meip
|
||||||
if (tp.core.useVM) periphIntNode := plic.intnode // seip
|
if (tp.core.useVM) periphIntNode := plic.intnode // seip
|
||||||
@ -123,10 +155,10 @@ trait HasRocketTiles extends HasTiles
|
|||||||
|
|
||||||
// 4. conditional crossing from core to PLIC
|
// 4. conditional crossing from core to PLIC
|
||||||
FlipRendering { implicit p =>
|
FlipRendering { implicit p =>
|
||||||
plic.intnode :=* wrapper.crossIntOut :=* wrapper.intOutwardNode
|
plic.intnode :=* rocket.crossIntOut :=* rocket.intOutwardNode
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper
|
rocket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,9 @@ trait GroundTestTileParams extends TileParams {
|
|||||||
|
|
||||||
case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]]
|
case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]]
|
||||||
|
|
||||||
abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) {
|
abstract class GroundTestTile(params: GroundTestTileParams)
|
||||||
|
(implicit p: Parameters)
|
||||||
|
extends BaseTile(params, crossing = SynchronousCrossing())(p) {
|
||||||
val intInwardNode: IntInwardNode = IntIdentityNode()
|
val intInwardNode: IntInwardNode = IntIdentityNode()
|
||||||
val intOutwardNode: IntOutwardNode = IntIdentityNode()
|
val intOutwardNode: IntOutwardNode = IntIdentityNode()
|
||||||
val slaveNode: TLInwardNode = TLIdentityNode()
|
val slaveNode: TLInwardNode = TLIdentityNode()
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.tile
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex.{CacheBlockBytes, SystemBusKey}
|
import freechips.rocketchip.coreplex._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
@ -144,8 +144,11 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Base class for all Tiles that use TileLink */
|
/** Base class for all Tiles that use TileLink */
|
||||||
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
abstract class BaseTile(
|
||||||
with HasTileParameters {
|
tileParams: TileParams,
|
||||||
|
val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends BareTile
|
||||||
|
with HasTileParameters
|
||||||
|
with HasCrossing {
|
||||||
def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]]
|
def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]]
|
||||||
def masterNode: TLOutwardNode
|
def masterNode: TLOutwardNode
|
||||||
def slaveNode: TLInwardNode
|
def slaveNode: TLInwardNode
|
||||||
@ -156,6 +159,7 @@ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends
|
|||||||
protected val tlMasterXbar = LazyModule(new TLXbar)
|
protected val tlMasterXbar = LazyModule(new TLXbar)
|
||||||
protected val tlSlaveXbar = LazyModule(new TLXbar)
|
protected val tlSlaveXbar = LazyModule(new TLXbar)
|
||||||
protected val intXbar = LazyModule(new IntXbar)
|
protected val intXbar = LazyModule(new IntXbar)
|
||||||
|
protected val intSinkNode = IntSinkNode(IntSinkPortSimple())
|
||||||
|
|
||||||
def connectTLSlave(node: TLNode, bytes: Int) {
|
def connectTLSlave(node: TLNode, bytes: Int) {
|
||||||
DisableMonitors { implicit p =>
|
DisableMonitors { implicit p =>
|
||||||
|
@ -19,11 +19,10 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
|
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
|
||||||
trait HasExternalInterrupts extends HasTileParameters {
|
trait HasExternalInterrupts { this: BaseTile =>
|
||||||
implicit val p: Parameters
|
|
||||||
val module: HasExternalInterruptsModule
|
|
||||||
|
|
||||||
val intInwardNode = IntSinkNode(IntSinkPortSimple())
|
val intInwardNode = intXbar.intnode
|
||||||
|
intSinkNode := intXbar.intnode
|
||||||
|
|
||||||
val intcDevice = new Device {
|
val intcDevice = new Device {
|
||||||
def describe(resources: ResourceBindings): Description = {
|
def describe(resources: ResourceBindings): Description = {
|
||||||
@ -37,7 +36,7 @@ trait HasExternalInterrupts extends HasTileParameters {
|
|||||||
ResourceBinding {
|
ResourceBinding {
|
||||||
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartId)))
|
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartId)))
|
||||||
|
|
||||||
intInwardNode.edges.in.flatMap(_.source.sources).map { case s =>
|
intSinkNode.edges.in.flatMap(_.source.sources).map { case s =>
|
||||||
for (i <- s.range.start until s.range.end) {
|
for (i <- s.range.start until s.range.end) {
|
||||||
csrIntMap.lift(i).foreach { j =>
|
csrIntMap.lift(i).foreach { j =>
|
||||||
s.resources.foreach { r =>
|
s.resources.foreach { r =>
|
||||||
@ -59,15 +58,6 @@ trait HasExternalInterrupts extends HasTileParameters {
|
|||||||
List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16)
|
List(65535, 3, 7, 11) ++ seip ++ List.tabulate(nlips)(_ + 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasExternalInterruptsBundle {
|
|
||||||
val outer: HasExternalInterrupts
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasExternalInterruptsModule {
|
|
||||||
val outer: HasExternalInterrupts
|
|
||||||
|
|
||||||
// go from flat diplomatic Interrupts to bundled TileInterrupts
|
// go from flat diplomatic Interrupts to bundled TileInterrupts
|
||||||
def decodeCoreInterrupts(core: TileInterrupts) {
|
def decodeCoreInterrupts(core: TileInterrupts) {
|
||||||
val async_ips = Seq(core.debug)
|
val async_ips = Seq(core.debug)
|
||||||
@ -80,7 +70,7 @@ trait HasExternalInterruptsModule {
|
|||||||
|
|
||||||
val core_ips = core.lip
|
val core_ips = core.lip
|
||||||
|
|
||||||
val (interrupts, _) = outer.intInwardNode.in(0)
|
val (interrupts, _) = intSinkNode.in(0)
|
||||||
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i }
|
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,9 @@ package freechips.rocketchip.tile
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.coreplex.CoreplexClockCrossing
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class RocketTileParams(
|
case class RocketTileParams(
|
||||||
@ -30,7 +28,10 @@ case class RocketTileParams(
|
|||||||
require(dcache.isDefined)
|
require(dcache.isDefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketTile(val rocketParams: RocketTileParams)(implicit p: Parameters) extends BaseTile(rocketParams)(p)
|
class RocketTile(
|
||||||
|
val rocketParams: RocketTileParams,
|
||||||
|
crossing: CoreplexClockCrossing)
|
||||||
|
(implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p)
|
||||||
with HasExternalInterrupts
|
with HasExternalInterrupts
|
||||||
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
||||||
with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend
|
with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend
|
||||||
@ -61,14 +62,13 @@ class RocketTileBundle(outer: RocketTile) extends BaseTileBundle(outer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer))
|
class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => new RocketTileBundle(outer))
|
||||||
with HasExternalInterruptsModule
|
|
||||||
with HasLazyRoCCModule
|
with HasLazyRoCCModule
|
||||||
with CanHaveScratchpadModule {
|
with CanHaveScratchpadModule {
|
||||||
|
|
||||||
val core = Module(p(BuildCore)(outer.p))
|
val core = Module(p(BuildCore)(outer.p))
|
||||||
val uncorrectable = RegInit(Bool(false))
|
val uncorrectable = RegInit(Bool(false))
|
||||||
|
|
||||||
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
|
outer.decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
|
||||||
outer.busErrorUnit.foreach { beu => core.io.interrupts.buserror.get := beu.module.io.interrupt }
|
outer.busErrorUnit.foreach { beu => core.io.interrupts.buserror.get := beu.module.io.interrupt }
|
||||||
core.io.hartid := io.hartid // Pass through the hartid
|
core.io.hartid := io.hartid // Pass through the hartid
|
||||||
io.trace.foreach { _ := core.io.trace }
|
io.trace.foreach { _ := core.io.trace }
|
||||||
@ -103,56 +103,3 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
|||||||
dcacheArb.io.requestor <> dcachePorts
|
dcacheArb.io.requestor <> dcachePorts
|
||||||
ptw.io.requestor <> ptwPorts
|
ptw.io.requestor <> ptwPorts
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketTileWrapperBundle[+L <: RocketTileWrapper](_outer: L) extends BaseTileBundle(_outer)
|
|
||||||
with CanHaltAndCatchFire {
|
|
||||||
val halt_and_catch_fire = _outer.rocket.module.io.halt_and_catch_fire.map(_.cloneType)
|
|
||||||
}
|
|
||||||
|
|
||||||
class RocketTileWrapper(
|
|
||||||
params: RocketTileParams,
|
|
||||||
val crossing: CoreplexClockCrossing)
|
|
||||||
(implicit p: Parameters) extends BaseTile(params) with HasCrossing {
|
|
||||||
|
|
||||||
val rocket = LazyModule(new RocketTile(params))
|
|
||||||
|
|
||||||
// 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 masterNode = crossing match {
|
|
||||||
case _: AsynchronousCrossing => rocket.masterNode
|
|
||||||
case SynchronousCrossing(b) =>
|
|
||||||
require (!params.boundaryBuffers || (b.depth >= 1 && !b.flow && !b.pipe), "Buffer misconfiguration creates feed-through paths")
|
|
||||||
rocket.masterNode
|
|
||||||
case RationalCrossing(dir) =>
|
|
||||||
require (dir != SlowToFast, "Misconfiguration? Core slower than fabric")
|
|
||||||
if (params.boundaryBuffers) {
|
|
||||||
masterBuffer.node :=* rocket.masterNode
|
|
||||||
} else {
|
|
||||||
rocket.masterNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
|
|
||||||
val slaveNode: TLInwardNode = crossing match {
|
|
||||||
case _: SynchronousCrossing => rocket.slaveNode // requirement already checked
|
|
||||||
case _: AsynchronousCrossing => rocket.slaveNode
|
|
||||||
case _: RationalCrossing =>
|
|
||||||
if (params.boundaryBuffers) {
|
|
||||||
DisableMonitors { implicit p => rocket.slaveNode :*= slaveBuffer.node }
|
|
||||||
} else {
|
|
||||||
rocket.slaveNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rocket.intInwardNode := intXbar.intnode
|
|
||||||
val intInwardNode = intXbar.intnode
|
|
||||||
val intOutwardNode = rocket.intOutwardNode
|
|
||||||
|
|
||||||
override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) {
|
|
||||||
// signals that do not change based on crossing type:
|
|
||||||
rocket.module.io.hartid := io.hartid
|
|
||||||
rocket.module.io.reset_vector := io.reset_vector
|
|
||||||
io.trace.foreach { _ := rocket.module.io.trace.get }
|
|
||||||
io.halt_and_catch_fire.foreach { _ := rocket.module.io.halt_and_catch_fire.get }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user