1
0

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:
Henry Cook 2017-12-13 19:00:29 -08:00
parent 9b82f1098d
commit ddaeedf2d0
7 changed files with 79 additions and 73 deletions

View File

@ -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

View 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
}
}

View File

@ -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
}
}

View File

@ -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))

View File

@ -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)

View File

@ -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

View File

@ -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)) {