Integrate with new Rocket tile API
This commit is contained in:
@@ -26,7 +26,7 @@ import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.spi._
|
||||
|
||||
import chipyard.{BuildTop, BuildSystem}
|
||||
import chipyard.{GenericTilesKey, GenericTileConfig}
|
||||
import chipyard.GenericCanAttachTile
|
||||
|
||||
/**
|
||||
* TODO: Why do we need this?
|
||||
@@ -65,11 +65,8 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) =>
|
||||
|
||||
class WithL2TLBs(entries: Int) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
|
||||
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
|
||||
case other => other
|
||||
case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nL2TLBEntries = entries))).convert
|
||||
}
|
||||
})
|
||||
|
||||
@@ -110,7 +107,6 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class WithTraceIO extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
@@ -124,10 +120,7 @@ class WithTraceIO extends Config((site, here, up) => {
|
||||
|
||||
class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nPerfCounters = n)))
|
||||
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nPerfCounters = n)))
|
||||
case other => other
|
||||
case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy(
|
||||
core = tp.tileParams.core.copy(nPerfCounters = n))).convert
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
package chipyard
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.runtime.universe._
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Config, Field, View}
|
||||
import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName}
|
||||
import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode
|
||||
import freechips.rocketchip.rocket._
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams}
|
||||
import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams}
|
||||
|
||||
case object CoreEntryKey extends Field[Seq[CoreEntryBase]](Nil)
|
||||
|
||||
// If this key is encountered by a GenericTilesKey extractor, throw immediately
|
||||
// Inside the body of GenericTileConfig, suppressed will be set to true to prevent the extractor from throwing
|
||||
case class GenericTilesKeyChecker(suppressed: Boolean) extends Field[Int](0)
|
||||
case class GenericTilesKeyImp(key: Field[Seq[TileParams]]) extends Field[Seq[GenericTileParams]](Nil)
|
||||
object GenericTilesKey {
|
||||
def apply(key: Field[Seq[TileParams]]) = GenericTilesKeyImp(key)
|
||||
def unapply(key: Any): Option[Field[Seq[TileParams]]] = key match {
|
||||
case GenericTilesKeyChecker(suppressed) if !suppressed => throw new Exception("GenericTilesKey must be in GenericTilesConfig")
|
||||
case GenericTilesKeyImp(key) => Some(key)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
// Base trait for all third-party core entries
|
||||
sealed trait CoreEntryBase {
|
||||
val name: String
|
||||
|
||||
def keyEqual(key: Any): Boolean
|
||||
def tileParamsLookup(implicit p: Parameters): Seq[TileParams]
|
||||
|
||||
def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode)
|
||||
(implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, () => BaseTile)]
|
||||
}
|
||||
|
||||
// Implementation of third-party core entries
|
||||
class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag](
|
||||
val name: String,
|
||||
tilesKey: Field[Seq[TileParamsT]],
|
||||
crossingKey: Field[Seq[RocketCrossingParams]]
|
||||
) extends CoreEntryBase {
|
||||
// Use reflection to get the tile's constructor
|
||||
private val mirror = runtimeMirror(getClass.getClassLoader)
|
||||
private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass)
|
||||
private val tileCtor = tileClass.getConstructors.filter(ctor => ctor.getParameterTypes()(4) == classOf[Parameters]).head
|
||||
|
||||
def keyEqual(key: Any) = key == tilesKey
|
||||
|
||||
// Tile parameter lookup using correct type
|
||||
def tileParamsLookup(implicit p: Parameters) = p(tilesKey)
|
||||
|
||||
// Instantiate a tile and zip it with its parameter info, used by subsystem
|
||||
def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode)
|
||||
(implicit p: Parameters, valName: ValName) = {
|
||||
// Sanity check of GenericTilesKey outside of GenericTileConfig
|
||||
// People would shoot themselves in the foot easily with this design, so a sanity check is necessary
|
||||
// Simply trigger the exception by looking up the checker key
|
||||
p(GenericTilesKeyChecker(false))
|
||||
|
||||
val tileParams = p(tilesKey)
|
||||
val crossings = crossingLookup(p(crossingKey), tileParams.size)
|
||||
(tileParams zip crossings) map {
|
||||
case (param, crossing) => (
|
||||
param,
|
||||
crossing,
|
||||
(() => LazyModule(tileCtor.newInstance(
|
||||
param,
|
||||
crossing,
|
||||
PriorityMuxHartIdFromSeq(tileParams),
|
||||
logicalTreeNode,
|
||||
p.asInstanceOf[Parameters]
|
||||
).asInstanceOf[TileT]))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Config fragment to register a core
|
||||
class RegisterCore[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag](
|
||||
name: String,
|
||||
tilesKey: Field[Seq[TileParamsT]],
|
||||
crossingKey: Field[Seq[RocketCrossingParams]]
|
||||
) extends Config((site, here, up) => {
|
||||
case CoreEntryKey => new CoreEntry[TileParamsT, TileT](name, tilesKey, crossingKey) +: up(CoreEntryKey)
|
||||
})
|
||||
|
||||
// The config used along with GenericTilesKey.
|
||||
// It change a lookup for registered tile parameter into a lookup with GenericTilesKey in the function body temporarily.
|
||||
class GenericTileConfig(f: (View, View, View) => PartialFunction[Any, Any]) extends Config(
|
||||
new Config((site, here, up) => {
|
||||
case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(true))
|
||||
case key if CoreManager.keyMatch(up, key) => up(GenericTilesKey(key.asInstanceOf[Field[Seq[TileParams]]])) map (t => t.convert)
|
||||
}) ++
|
||||
new Config(f) ++
|
||||
new Config((site, here, up) => {
|
||||
case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(false))
|
||||
case GenericTilesKey(key) => up(key) map (t => new GenericTileParams(t))
|
||||
})
|
||||
)
|
||||
|
||||
// A list of all cores.
|
||||
object CoreManager {
|
||||
// Built-in cores.
|
||||
val base_cores: List[CoreEntryBase] = List(
|
||||
new CoreEntry[RocketTileParams, RocketTile]("Rocket", RocketTilesKey, RocketCrossingKey),
|
||||
new CoreEntry[BoomTileParams, BoomTile]("Boom", BoomTilesKey, BoomCrossingKey),
|
||||
new CoreEntry[ArianeTileParams, ArianeTile]("Ariane", ArianeTilesKey, ArianeCrossingKey)
|
||||
)
|
||||
|
||||
// Look up all cores that are registered in the current config view.
|
||||
def cores(view: View): Seq[CoreEntryBase] = view(CoreEntryKey) ++ base_cores
|
||||
|
||||
// Check if the key is among the currently registered cores.
|
||||
def keyMatch(view: View, key: Any) = (cores(view) filter (c => c.keyEqual(key))).size != 0
|
||||
}
|
||||
@@ -6,15 +6,12 @@ import scala.reflect.runtime.universe._
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Config, Field, View}
|
||||
import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName}
|
||||
import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode
|
||||
import freechips.rocketchip.rocket._
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams}
|
||||
import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams}
|
||||
|
||||
// Trait for generic case class of base trait for copying
|
||||
trait ConcreteBaseTrait[Base] {
|
||||
this: Product =>
|
||||
@@ -146,3 +143,35 @@ case class GenericTileParams(
|
||||
_origin = tileParams
|
||||
)
|
||||
}
|
||||
|
||||
case class GenericTileCrossingParamsLike(
|
||||
val crossingType: ClockCrossingType,
|
||||
val master: TilePortParamsLike,
|
||||
val slave: TilePortParamsLike,
|
||||
val _origin: TileCrossingParamsLike
|
||||
) extends TileCrossingParamsLike with ConcreteBaseTrait[TileCrossingParamsLike] {
|
||||
def this(crossing: TileCrossingParamsLike) = this(
|
||||
crossingType = crossing.crossingType,
|
||||
master = crossing.master,
|
||||
slave = crossing.slave,
|
||||
_origin = crossing
|
||||
)
|
||||
}
|
||||
|
||||
case class GenericCanAttachTileImpl(
|
||||
val tileParams: GenericTileParams,
|
||||
val crossingParams: TileCrossingParamsLike,
|
||||
val lookup: LookupByHartIdImpl,
|
||||
val _origin: CanAttachTile,
|
||||
) extends ConcreteBaseTrait[CanAttachTile] {
|
||||
def this(param: CanAttachTile) = this(
|
||||
tileParams = new GenericTileParams(param.tileParams),
|
||||
crossingParams = new GenericTileCrossingParamsLike(param.crossingParams),
|
||||
lookup = param.lookup,
|
||||
_origin = param
|
||||
)
|
||||
}
|
||||
|
||||
object GenericCanAttachTile {
|
||||
def unapply(tile: CanAttachTile) = Some(new GenericCanAttachTileImpl(tile))
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package chipyard
|
||||
import scala.collection.mutable.{LinkedHashSet}
|
||||
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tile.{XLen}
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import freechips.rocketchip.tile.{XLen, TileParams}
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite}
|
||||
|
||||
import boom.common.{BoomTileAttachParams}
|
||||
@@ -83,16 +83,17 @@ class TestSuiteHelper
|
||||
if (cfg.fLen >= 64)
|
||||
addSuites(env.map(rv64ud))
|
||||
}
|
||||
if (coreParams.useAtomics) {
|
||||
if (tileParams.dcache.flatMap(_.scratch).isEmpty)
|
||||
addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
|
||||
else
|
||||
addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
|
||||
}
|
||||
if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
|
||||
val (rvi, rvu) =
|
||||
if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
|
||||
else ((if (vm) rv32i else rv32pi), rv32u)
|
||||
}
|
||||
if (coreParams.useAtomics) {
|
||||
if (tileParams.dcache.flatMap(_.scratch).isEmpty)
|
||||
addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
|
||||
else
|
||||
addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
|
||||
}
|
||||
if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
|
||||
val (rvi, rvu) =
|
||||
if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
|
||||
else ((if (vm) rv32i else rv32pi), rv32u)
|
||||
|
||||
addSuites(rvi.map(_("p")))
|
||||
addSuites(rvu.map(_("p")))
|
||||
@@ -116,4 +117,3 @@ case object TestSuitesKey extends Field[(Seq[TileParams], TestSuiteHelper, Param
|
||||
class WithTestSuite(suiteFactory: (Seq[TileParams], TestSuiteHelper, Parameters) => Unit) extends Config((site, here, up) => {
|
||||
case TestSuitesKey => suiteFactory
|
||||
})
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@ import firrtl.options.Viewer.view
|
||||
import freechips.rocketchip.stage.RocketChipOptions
|
||||
import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation}
|
||||
import freechips.rocketchip.system.{RocketTestSuite, TestGeneration}
|
||||
import freechips.rocketchip.subsystem.{TilesLocated, InSubsystem}
|
||||
import freechips.rocketchip.util.HasRocketChipStageUtils
|
||||
import freechips.rocketchip.tile.XLen
|
||||
|
||||
import chipyard.{TestSuiteHelper, CoreManager}
|
||||
import chipyard.TestSuiteHelper
|
||||
import chipyard.TestSuitesKey
|
||||
|
||||
class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
|
||||
@@ -34,12 +35,13 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS
|
||||
val suiteHelper = new TestSuiteHelper
|
||||
// Use Xlen as a proxy for detecting if we are a processor-like target
|
||||
// The underlying test suites expect this field to be defined
|
||||
val tileParams = p(TilesLocated(InSubsystem)) map (tp => tp.tileParams)
|
||||
if (p.lift(XLen).nonEmpty)
|
||||
// If a custom test suite is set up, use the custom test suite
|
||||
if (p.lift(TestSuitesKey).nonEmpty)
|
||||
CoreManager.cores(p) map (core => p(TestSuitesKey).apply(core.tileParamsLookup, suiteHelper, p))
|
||||
p(TestSuitesKey).apply(tileParams, suiteHelper, p)
|
||||
else
|
||||
CoreManager.cores(p) map (core => suiteHelper.addGenericTestSuites(core.tileParamsLookup))
|
||||
suiteHelper.addGenericTestSuites(tileParams)
|
||||
|
||||
// if hwacha parameter exists then generate its tests
|
||||
// TODO: find a more elegant way to do this. either through
|
||||
|
||||
Reference in New Issue
Block a user