Skip to content

Commit

Permalink
Merge pull request #2504 from chipsalliance/instantiate-all-tiles-bef…
Browse files Browse the repository at this point in the history
…ore-connecting

Standardize Tile Instantiation and Attachment
  • Loading branch information
hcook authored Jun 18, 2020
2 parents 35eb1ca + 77532ca commit 1cec6e6
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object LogicalModuleTree {

def rootLogicalTreeNode: LogicalTreeNode = {
val roots = tree.collect { case (k, _) if !tree.exists(_._2.contains(k)) => k }
assert(roots.size == 1, "Logical Tree contains more than one root.")
require(roots.size == 1, s"Logical Tree contains more than one root:\n$roots")
roots.head
}

Expand Down
73 changes: 52 additions & 21 deletions src/main/scala/groundtest/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,67 @@ package freechips.rocketchip.groundtest

import Chisel._
import freechips.rocketchip.config.Config
import freechips.rocketchip.devices.tilelink.{CLINTKey, PLICKey}
import freechips.rocketchip.devices.debug.{DebugModuleKey}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.system.BaseConfig
import freechips.rocketchip.rocket.{DCacheParams}
import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
import freechips.rocketchip.tile.{XLen}

/** Actual testing target Configs */

class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseConfig)
class TraceGenConfig extends Config(
new WithTraceGen(2)() ++
new GroundTestBaseConfig
)

class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)
class TraceGenBufferlessConfig extends Config(
new WithBufferlessBroadcastHub ++
new TraceGenConfig
)

/* Composable Configs to set individual parameters */

class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192) extends Config((site, here, up) => {
case GroundTestTilesKey => params.map { dcp => TraceGenParams(
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 32,
addrBag = {
val nSets = dcp.nSets
val nWays = dcp.nWays
val blockOffset = site(SystemBusKey).blockOffset
val nBeats = site(SystemBusKey).blockBeats
List.tabulate(nWays) { i =>
Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
}.flatten
},
maxRequests = nReqs,
memStart = site(ExtMem).get.master.base,
numGens = params.size)
class GroundTestBaseConfig extends Config(
new BaseConfig().alter((site,here,up) => {
case DebugModuleKey => None
case CLINTKey => None
case PLICKey => None
})
)

class WithTraceGen(
n: Int = 2,
overrideIdOffset: Option[Int] = None,
overrideMemOffset: Option[BigInt] = None)(
params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nSets = 16, nWays = 1) },
nReqs: Int = 8192
) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site)
val idOffset = overrideIdOffset.getOrElse(prev.size)
val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L)
params.zipWithIndex.map { case (dcp, i) =>
TraceGenTileAttachParams(
tileParams = TraceGenParams(
hartId = i + idOffset,
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 32,
addrBag = {
val nSets = dcp.nSets
val nWays = dcp.nWays
val blockOffset = site(SystemBusKey).blockOffset
val nBeats = site(SystemBusKey).blockBeats
List.tabulate(nWays) { i =>
Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
}.flatten
},
maxRequests = nReqs,
memStart = memOffset,
numGens = params.size),
crossingParams = RocketCrossingParams()
)
} ++ prev
}
case MaxHartIdBits => log2Up(params.size)
})
40 changes: 17 additions & 23 deletions src/main/scala/groundtest/GroundTestSubsystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,24 @@
package freechips.rocketchip.groundtest

import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.diplomaticobjectmodel.model.OMInterrupt
import freechips.rocketchip.interrupts._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.tile._

import scala.math.max

case object TileId extends Field[Int]

class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem
with CanHaveMasterAXI4MemPort {
val tileParams = p(GroundTestTilesKey)
val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(c.build(i, p)) }

tiles.map(_.masterNode).foreach { m =>
sbus.fromTile(None, buffer = BufferParams.default){ m }
}

import chisel3.dontTouch
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.diplomacy.{AddressSet, LazyModule}
import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
import freechips.rocketchip.subsystem.{BaseSubsystem, BaseSubsystemModuleImp, HasTiles, CanHaveMasterAXI4MemPort}
import freechips.rocketchip.tilelink.{TLRAM, TLFragmenter}

class GroundTestSubsystem(implicit p: Parameters)
extends BaseSubsystem
with HasTiles
with CanHaveMasterAXI4MemPort
{
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), beatBytes=pbus.beatBytes))
pbus.coupleTo("TestRAM") { testram.node := TLFragmenter(pbus) := _ }

// No cores to monitor
def coreMonitorBundles = Nil

// No PLIC in ground test; so just sink the interrupts to nowhere
IntSinkNode(IntSinkPortSimple()) :=* ibus.toPLIC

Expand All @@ -38,6 +32,6 @@ class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends

outer.tiles.zipWithIndex.map { case(t, i) => t.module.constants.hartid := UInt(i) }

val status = DebugCombiner(outer.tiles.map(_.module.status))
success := status.finished
val status = dontTouch(DebugCombiner(outer.tiles.collect { case t: GroundTestTile => t.module.status }))
success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR
}
3 changes: 0 additions & 3 deletions src/main/scala/groundtest/Status.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ import Chisel._
import freechips.rocketchip.util.ValidMux

class GroundTestStatus extends Bundle {
val finished = Bool(OUTPUT)
val timeout = Valid(UInt(width = 4))
val error = Valid(UInt(width = 4))
}

object DebugCombiner {
def apply(debugs: Seq[GroundTestStatus]): GroundTestStatus = {
val out = Wire(new GroundTestStatus)
out.finished := debugs.map(_.finished).reduce(_ && _)
out.timeout := ValidMux(debugs.map(_.timeout))
out.error := ValidMux(debugs.map(_.error))
out
}
}

20 changes: 9 additions & 11 deletions src/main/scala/groundtest/Tile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ trait GroundTestTileParams extends TileParams {
val memStart: BigInt
val maxRequests: Int
val numGens: Int

def build(i: Int, p: Parameters): GroundTestTile

val icache = Some(ICacheParams())
val btb = None
Expand All @@ -28,18 +26,18 @@ trait GroundTestTileParams extends TileParams {
val dataScratchpadBytes = 0
}

case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]]

abstract class GroundTestTile private (params: GroundTestTileParams, x: ClockCrossingType, q: Parameters)
extends BaseTile(params, x, HartsWontDeduplicate(params), q)
abstract class GroundTestTile(
params: GroundTestTileParams,
crossing: ClockCrossingType,
lookup: LookupByHartIdImpl,
q: Parameters
) extends BaseTile(params, crossing, lookup, q)
with SinksExternalInterrupts
with SourcesExternalNotifications
{
def this(params: GroundTestTileParams)(implicit p: Parameters) = this(params, SynchronousCrossing(), p)
val intInwardNode: IntInwardNode = IntIdentityNode()
val cpuDevice: SimpleDevice = new SimpleDevice("groundtest", Nil)
val intOutwardNode: IntOutwardNode = IntIdentityNode()
val slaveNode: TLInwardNode = TLIdentityNode()
val ceaseNode: IntOutwardNode = IntIdentityNode()
val haltNode: IntOutwardNode = IntIdentityNode()
val wfiNode: IntOutwardNode = IntIdentityNode()

val dcacheOpt = params.dcache.map { dc => LazyModule(
if (dc.nMSHRs == 0) new DCache(hartId, crossing)
Expand Down
46 changes: 36 additions & 10 deletions src/main/scala/groundtest/TraceGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
package freechips.rocketchip.groundtest

import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.diplomacy.{ClockCrossingType}
import freechips.rocketchip.rocket._
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CanAttachTile}
import freechips.rocketchip.util._

// =======
Expand Down Expand Up @@ -57,15 +59,19 @@ import freechips.rocketchip.util._
// to repeatedly recompile with a different address bag.)

case class TraceGenParams(
dcache: Option[DCacheParams] = Some(DCacheParams()),
wordBits: Int, // p(XLen)
addrBits: Int, // p(PAddrBits)
addrBag: List[BigInt], // p(AddressBag)
maxRequests: Int,
memStart: BigInt, //p(ExtMem).base
numGens: Int) extends GroundTestTileParams {
def build(i: Int, p: Parameters): GroundTestTile = new TraceGenTile(i, this)(p)
val hartId = 0
numGens: Int,
dcache: Option[DCacheParams] = Some(DCacheParams()),
hartId: Int = 0
) extends InstantiableTileParams[TraceGenTile] with GroundTestTileParams
{
def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): TraceGenTile = {
new TraceGenTile(this, crossing, lookup)
}
val beuAddr = None
val blockerCtrlAddr = None
val name = None
Expand Down Expand Up @@ -94,6 +100,15 @@ trait HasTraceGenParams {
require((1 << logAddressBagLen) == addressBagLen)
}

case class TraceGenTileAttachParams(
tileParams: TraceGenParams,
crossingParams: TileCrossingParamsLike
) extends CanAttachTile {
type TileType = TraceGenTile
val lookup: LookupByHartIdImpl = HartsWontDeduplicate(tileParams)
}


// ============
// Trace format
// ============
Expand Down Expand Up @@ -578,9 +593,18 @@ class TraceGenerator(val params: TraceGenParams)(implicit val p: Parameters) ext
// Trace-generator wrapper
// =======================

class TraceGenTile(hack: Int, val id: Int, val params: TraceGenParams, q: Parameters) extends GroundTestTile(params)(q) {
def this(id: Int, params: TraceGenParams)(implicit p: Parameters) = this(0, id, params, p)
val masterNode: TLOutwardNode = TLIdentityNode() := visibilityNode := dcacheOpt.map(_.node).getOrElse(TLIdentityNode())
class TraceGenTile private(
val params: TraceGenParams,
crossing: ClockCrossingType,
lookup: LookupByHartIdImpl,
q: Parameters
) extends GroundTestTile(params, crossing, lookup, q)
{
def this(params: TraceGenParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
this(params, crossing.crossingType, lookup, p)

val masterNode: TLOutwardNode = TLIdentityNode() := visibilityNode := dcacheOpt.map(_.node).getOrElse(TLTempNode())

override lazy val module = new TraceGenTileModuleImp(this)
}

Expand All @@ -595,10 +619,12 @@ class TraceGenTileModuleImp(outer: TraceGenTile) extends GroundTestTileModuleImp
dcache.module.io.cpu <> dcacheIF.io.cache
}

status.finished := tracegen.io.finished
outer.reportCease(Some(tracegen.io.finished))
outer.reportHalt(Some(tracegen.io.timeout))
outer.reportWFI(None)
status.timeout.valid := tracegen.io.timeout
status.timeout.bits := UInt(0)
status.error.valid := Bool(false)

assert(!tracegen.io.timeout, s"TraceGen tile ${outer.id}: request timed out")
assert(!tracegen.io.timeout, s"TraceGen tile ${outer.tileParams.hartId}: request timed out")
}
36 changes: 29 additions & 7 deletions src/main/scala/subsystem/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class BaseSubsystemConfig extends Config ((site, here, up) => {
// Tile parameters
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
case XLen => 64 // Applies to all cores
case MaxHartIdBits => log2Up(site(RocketTilesKey).size)
case MaxHartIdBits => log2Up(site(TilesLocated(InSubsystem)).map(_.tileParams.hartId).max+1)
// Interconnect parameters
case SystemBusKey => SystemBusParams(
beatBytes = site(XLen)/8,
Expand All @@ -41,6 +41,8 @@ class BaseSubsystemConfig extends Config ((site, here, up) => {
case DebugModuleKey => Some(DefaultDebugModuleParams(site(XLen)))
case CLINTKey => Some(CLINTParams())
case PLICKey => Some(PLICParams())
case TilesLocated(InSubsystem) =>
LegacyTileFieldHelper(site(RocketTilesKey), site(RocketCrossingKey), RocketTileAttachParams.apply _)
})

/* Composable partial function Configs to set individual parameters */
Expand Down Expand Up @@ -75,8 +77,10 @@ class WithCoherentBusTopology extends Config((site, here, up) => {
l2 = site(BankedL2Key)))
})

class WithNBigCores(n: Int) extends Config((site, here, up) => {
class WithNBigCores(n: Int, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
case RocketTilesKey => {
val prev = up(RocketTilesKey, site)
val idOffset = overrideIdOffset.getOrElse(prev.size)
val big = RocketTileParams(
core = RocketCoreParams(mulDiv = Some(MulDivParams(
mulUnroll = 8,
Expand All @@ -89,12 +93,14 @@ class WithNBigCores(n: Int) extends Config((site, here, up) => {
icache = Some(ICacheParams(
rowBits = site(SystemBusKey).beatBits,
blockBytes = site(CacheBlockBytes))))
List.tabulate(n)(i => big.copy(hartId = i))
List.tabulate(n)(i => big.copy(hartId = i + idOffset)) ++ prev
}
})

class WithNMedCores(n: Int) extends Config((site, here, up) => {
class WithNMedCores(n: Int, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
case RocketTilesKey => {
val prev = up(RocketTilesKey, site)
val idOffset = overrideIdOffset.getOrElse(prev.size)
val med = RocketTileParams(
core = RocketCoreParams(fpu = None),
btb = None,
Expand All @@ -111,12 +117,14 @@ class WithNMedCores(n: Int) extends Config((site, here, up) => {
nWays = 1,
nTLBEntries = 4,
blockBytes = site(CacheBlockBytes))))
List.tabulate(n)(i => med.copy(hartId = i))
List.tabulate(n)(i => med.copy(hartId = i + idOffset)) ++ prev
}
})

class WithNSmallCores(n: Int) extends Config((site, here, up) => {
class WithNSmallCores(n: Int, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
case RocketTilesKey => {
val prev = up(RocketTilesKey, site)
val idOffset = overrideIdOffset.getOrElse(prev.size)
val small = RocketTileParams(
core = RocketCoreParams(useVM = false, fpu = None),
btb = None,
Expand All @@ -133,7 +141,7 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => {
nWays = 1,
nTLBEntries = 4,
blockBytes = site(CacheBlockBytes))))
List.tabulate(n)(i => small.copy(hartId = i))
List.tabulate(n)(i => small.copy(hartId = i + idOffset)) ++ prev
}
})

Expand Down Expand Up @@ -410,3 +418,17 @@ class WithScratchpadsOnly extends Config((site, here, up) => {
scratch = Some(0x80000000L))))
}
})

/** Boilerplate code for translating between the old XTilesParamsKey/XTilesCrossingKey pattern and new TilesLocated pattern */
object LegacyTileFieldHelper {
def apply[TPT <: InstantiableTileParams[_], TCT <: TileCrossingParamsLike, TAP <: CanAttachTile](
tileParams: Seq[TPT],
tcp: Seq[TCT],
apply: (TPT, TCT, LookupByHartIdImpl) => TAP): Seq[TAP] =
{
val crossingParams = heterogeneousOrGlobalSetting(tcp, tileParams.size)
tileParams.zip(crossingParams).map { case (t, c) =>
apply(t, c, PriorityMuxHartIdFromSeq(tileParams))
}
}
}
Loading

0 comments on commit 1cec6e6

Please sign in to comment.