Integrate with new Rocket tile API

This commit is contained in:
Zitao Fang
2020-06-24 20:55:37 -07:00
parent df90442088
commit 1c5bc7d0ff
5 changed files with 56 additions and 155 deletions

View File

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

View File

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

View File

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

View File

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

View File

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