coreplex: make HasTiles more generic
HasTiles now deals with only extremely general tile IOs. Some RocketTiles specific behavior moved into RocketCoreplex. BaseTile now has optional LocalInterruptNode.
This commit is contained in:
parent
9b82f1098d
commit
ddaeedf2d0
@ -5,11 +5,8 @@ package freechips.rocketchip.coreplex
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants}
|
|
||||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
/** BareCoreplex is the root class for creating a coreplex sub-system */
|
/** BareCoreplex is the root class for creating a coreplex sub-system */
|
||||||
@ -27,25 +24,6 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod
|
|||||||
println(outer.dts)
|
println(outer.dts)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasTiles extends HasSystemBus {
|
|
||||||
protected def tileParams: Seq[TileParams]
|
|
||||||
def nRocketTiles = tileParams.size
|
|
||||||
def hartIdList = tileParams.map(_.hartid)
|
|
||||||
|
|
||||||
// Handle interrupts to be routed directly into each tile
|
|
||||||
// TODO: figure out how to merge the localIntNodes and coreIntXbar
|
|
||||||
def localIntCounts = tileParams.map(_.core.nLocalInterrupts)
|
|
||||||
lazy val localIntNodes = tileParams.zipWithIndex map { case (t, i) => {
|
|
||||||
(t.core.nLocalInterrupts > 0).option({
|
|
||||||
val n = LazyModule(new IntXbar)
|
|
||||||
n.suggestName(s"localIntXbar_${i}")
|
|
||||||
n.intnode})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val tiles: Seq[BaseTile]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Base Coreplex class with no peripheral devices or ports added */
|
/** Base Coreplex class with no peripheral devices or ports added */
|
||||||
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
||||||
with HasInterruptBus
|
with HasInterruptBus
|
||||||
@ -80,46 +58,6 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
|
|
||||||
with HasExternallyDrivenTileConstants
|
|
||||||
with Clocked
|
|
||||||
|
|
||||||
trait HasTilesBundle {
|
|
||||||
val tile_inputs: Vec[ClockedTileInputs]
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasTilesModuleImp extends LazyModuleImp
|
|
||||||
with HasTilesBundle
|
|
||||||
with HasResetVectorWire {
|
|
||||||
val outer: HasTiles
|
|
||||||
|
|
||||||
def resetVectorBits: Int = {
|
|
||||||
// Consider using the minimum over all widths, rather than enforcing homogeneity
|
|
||||||
val vectors = outer.tiles.map(_.module.io.reset_vector)
|
|
||||||
require(vectors.tail.forall(_.getWidth == vectors.head.getWidth))
|
|
||||||
vectors.head.getWidth
|
|
||||||
}
|
|
||||||
val tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedTileInputs()(p.alterPartial {
|
|
||||||
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
|
||||||
})))
|
|
||||||
|
|
||||||
// Unconditionally wire up the non-diplomatic tile inputs
|
|
||||||
outer.tiles.map(_.module).zip(tile_inputs).foreach { case(tile, wire) =>
|
|
||||||
tile.clock := wire.clock
|
|
||||||
tile.reset := wire.reset
|
|
||||||
tile.io.hartid := wire.hartid
|
|
||||||
tile.io.reset_vector := wire.reset_vector
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default values for tile inputs; may be overriden in other traits
|
|
||||||
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
|
||||||
wire.clock := clock
|
|
||||||
wire.reset := reset
|
|
||||||
wire.hartid := UInt(i)
|
|
||||||
wire.reset_vector := global_reset_vector
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
|
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
|
||||||
println("Generated Address Map")
|
println("Generated Address Map")
|
||||||
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
|
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
|
||||||
|
52
src/main/scala/coreplex/HasTiles.scala
Normal file
52
src/main/scala/coreplex/HasTiles.scala
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.coreplex
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.interrupts._
|
||||||
|
import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants}
|
||||||
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
|
||||||
|
with HasExternallyDrivenTileConstants
|
||||||
|
with Clocked
|
||||||
|
|
||||||
|
trait HasTiles extends HasSystemBus {
|
||||||
|
val tiles: Seq[BaseTile]
|
||||||
|
protected def tileParams: Seq[TileParams]
|
||||||
|
def nTiles: Int = tileParams.size
|
||||||
|
def hartIdList: Seq[Int] = tileParams.map(_.hartid)
|
||||||
|
def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasTilesBundle {
|
||||||
|
val tile_inputs: Vec[ClockedTileInputs]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasTilesModuleImp extends LazyModuleImp
|
||||||
|
with HasTilesBundle
|
||||||
|
with HasResetVectorWire {
|
||||||
|
val outer: HasTiles
|
||||||
|
|
||||||
|
def resetVectorBits: Int = {
|
||||||
|
// Consider using the minimum over all widths, rather than enforcing homogeneity
|
||||||
|
val vectors = outer.tiles.map(_.module.io.reset_vector)
|
||||||
|
require(vectors.tail.forall(_.getWidth == vectors.head.getWidth))
|
||||||
|
vectors.head.getWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
val tile_inputs = Wire(Vec(outer.nTiles, new ClockedTileInputs()(p.alterPartial {
|
||||||
|
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
||||||
|
})))
|
||||||
|
|
||||||
|
// Unconditionally wire up the non-diplomatic tile inputs
|
||||||
|
outer.tiles.map(_.module).zip(tile_inputs).foreach { case(tile, wire) =>
|
||||||
|
tile.clock := wire.clock
|
||||||
|
tile.reset := wire.reset
|
||||||
|
tile.io.hartid := wire.hartid
|
||||||
|
tile.io.reset_vector := wire.reset_vector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,19 +67,19 @@ trait HasRocketTiles extends HasTiles
|
|||||||
with HasPeripheryDebug {
|
with HasPeripheryDebug {
|
||||||
val module: HasRocketTilesModuleImp
|
val module: HasRocketTilesModuleImp
|
||||||
|
|
||||||
protected val tileParams = p(RocketTilesKey)
|
protected val rocketTileParams = p(RocketTilesKey)
|
||||||
private val NumRocketTiles = tileParams.size
|
private val NumRocketTiles = rocketTileParams.size
|
||||||
private val crossingParams = p(RocketCrossingKey)
|
private val crossingParams = p(RocketCrossingKey)
|
||||||
private val crossings = crossingParams.size match {
|
private val crossings = crossingParams.size match {
|
||||||
case 1 => List.fill(NumRocketTiles) { crossingParams.head }
|
case 1 => List.fill(NumRocketTiles) { crossingParams.head }
|
||||||
case NumRocketTiles => crossingParams
|
case NumRocketTiles => crossingParams
|
||||||
case _ => throw new Exception("RocketCrossingKey.size must == 1 or == RocketTilesKey.size")
|
case _ => throw new Exception("RocketCrossingKey.size must == 1 or == RocketTilesKey.size")
|
||||||
}
|
}
|
||||||
private val crossingTuples = localIntNodes.zip(tileParams).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 wrapper for each tile that will wire it to coreplex devices and crossbars,
|
||||||
// according to the specified type of clock crossing.
|
// according to the specified type of clock crossing.
|
||||||
val tiles: Seq[BaseTile] = crossingTuples.map { case ((lip, 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 wrapper = LazyModule(new RocketTileWrapper(
|
||||||
@ -109,18 +109,20 @@ trait HasRocketTiles extends HasTiles
|
|||||||
// NOTE: The order of calls to := matters! They must match how interrupts
|
// NOTE: The order of calls to := matters! They must match how interrupts
|
||||||
// are decoded from rocket.intNode inside the tile.
|
// are decoded from rocket.intNode inside the tile.
|
||||||
|
|
||||||
wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode // 1. always async crossign
|
// 1. always async crossing for debug
|
||||||
|
wrapper.intXbar.intnode := wrapper { IntSyncCrossingSink(3) } := debug.intnode
|
||||||
|
|
||||||
// 2. clint+plic conditionak crossing
|
// 2. clint+plic conditionally crossing
|
||||||
val periphIntNode = wrapper.intXbar.intnode :=* wrapper.crossIntIn
|
val periphIntNode = wrapper.intXbar.intnode :=* wrapper.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
|
||||||
|
|
||||||
lip.foreach { wrapper.intXbar.intnode := _ } // 3. lip never crosses
|
// 3. local interrupts never cross
|
||||||
|
// this.localIntNode is wired up externally // lip
|
||||||
|
|
||||||
// From core to PLIC
|
// 4. conditional crossing from core to PLIC
|
||||||
wrapper.rocket.intOutputNode.foreach { i => // 4. conditional crossing
|
wrapper.rocket.intOutputNode.foreach { i =>
|
||||||
FlipRendering { implicit p =>
|
FlipRendering { implicit p =>
|
||||||
plic.intnode :=* wrapper.crossIntOut :=* i
|
plic.intnode :=* wrapper.crossIntOut :=* i
|
||||||
}
|
}
|
||||||
@ -137,8 +139,17 @@ trait HasRocketTilesModuleImp extends HasTilesModuleImp
|
|||||||
|
|
||||||
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
||||||
with HasRocketTiles {
|
with HasRocketTiles {
|
||||||
|
val tiles = rocketTiles
|
||||||
|
def tileParams = rocketTiles.map(_.tileParams)
|
||||||
override lazy val module = new RocketCoreplexModule(this)
|
override lazy val module = new RocketCoreplexModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
|
class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
|
||||||
with HasRocketTilesModuleImp
|
with HasRocketTilesModuleImp {
|
||||||
|
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
||||||
|
wire.clock := clock
|
||||||
|
wire.reset := reset
|
||||||
|
wire.hartid := UInt(i)
|
||||||
|
wire.reset_vector := global_reset_vector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ 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)(p) {
|
||||||
val slave = None
|
val slave = None
|
||||||
|
val localIntNode = None
|
||||||
val dcacheOpt = params.dcache.map { dc => LazyModule(new DCache(0)) }
|
val dcacheOpt = params.dcache.map { dc => LazyModule(new DCache(0)) }
|
||||||
|
|
||||||
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
||||||
|
@ -6,6 +6,7 @@ import Chisel._
|
|||||||
|
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
@ -111,6 +112,7 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters {
|
|||||||
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
||||||
with HasTileParameters {
|
with HasTileParameters {
|
||||||
def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]]
|
def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]]
|
||||||
|
val localIntNode: Option[IntInwardNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
abstract class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.tile
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
@ -23,6 +23,7 @@ trait HasExternalInterrupts extends HasTileParameters {
|
|||||||
val module: HasExternalInterruptsModule
|
val module: HasExternalInterruptsModule
|
||||||
|
|
||||||
val intNode = IntSinkNode(IntSinkPortSimple())
|
val intNode = IntSinkNode(IntSinkPortSimple())
|
||||||
|
val localIntNode: Option[IntInwardNode] = None
|
||||||
|
|
||||||
// TODO: the order of the following two functions must match, and
|
// TODO: the order of the following two functions must match, and
|
||||||
// also match the order which things are connected to the
|
// also match the order which things are connected to the
|
||||||
|
@ -230,6 +230,7 @@ class RocketTileWrapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val intXbar = LazyModule(new IntXbar)
|
val intXbar = LazyModule(new IntXbar)
|
||||||
|
val localIntNode = Some(intXbar.intnode)
|
||||||
rocket.intNode := intXbar.intnode
|
rocket.intNode := intXbar.intnode
|
||||||
|
|
||||||
override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) {
|
override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user