Fix no-coalescer config by removing coreTagWidth from L1 config

coreTagWidth logic in WithVortexL1Banks doesn't work, because
VortexL1Key is defined before the CoalescerKey and therefore
WithVortexL1Banks fragment has no way of knowing if coalescer is
defined.  Instead, figure out the core-side tag width within
VortexBankImp by querying the TL parameters.

The downside of this is that since VortexBankPassthrough's client node
no longer has a way of knowing the core tag width before the Diplomacy
phase, we need to set its sourceId bits as a fixed constant. A require
is in place to ensure no truncation of core-side's sourceId.
This commit is contained in:
Hansung Kim
2024-05-25 15:08:45 -07:00
parent 18e6a1f82d
commit 114dd75f2f
3 changed files with 34 additions and 33 deletions

View File

@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._
import chisel3.experimental._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
import freechips.rocketchip.tilelink._
import org.chipsalliance.cde.config.{Parameters, Field}
@@ -14,15 +15,11 @@ case class VortexL1Config(
numBanks: Int,
inputSize: Int, // This is the read/write granularity of the L1 cache
cacheLineSize: Int,
coreTagWidth: Int,
writeInfoReqQSize: Int,
mshrSize: Int,
memSideSourceIds: Int,
uncachedAddrSets: Seq[AddressSet]
) {
def coreTagPlusSizeWidth: Int = {
log2Ceil(inputSize) + coreTagWidth
}
// NOTE: This assertion depends on the fact that the Vortex cache is
// configured to have 1 bank, and that it uses MSHR id as the tag of
// memory-side requests. Otherwise, it will append bank id to the tag as
@@ -39,7 +36,6 @@ object defaultVortexL1Config
numBanks = 4,
inputSize = 16,
cacheLineSize = 16,
coreTagWidth = 8,
writeInfoReqQSize = 16,
mshrSize = 8,
memSideSourceIds = 8,
@@ -95,13 +91,18 @@ class VortexBankPassThrough(config: VortexL1Config)(implicit p: Parameters)
)
)
// HACK: Set arbitrarily since we cannot query the coresideNode's sourceId
// here. See comment on the require below.
// @perf: This is quite high
val sourceWidth = 9
// Master node to downstream
val clientParam = Seq(
TLMasterPortParameters.v1(
clients = Seq(
TLMasterParameters.v1(
name = "VortexBankPassthrough",
sourceId = IdRange(0, 1 << config.coreTagWidth),
sourceId = IdRange(0, 1 << sourceWidth),
supportsProbe = TransferSizes(1, config.cacheLineSize),
supportsGet = TransferSizes(1, config.cacheLineSize),
supportsPutFull = TransferSizes(1, config.cacheLineSize),
@@ -121,6 +122,13 @@ class VortexBankPassThrough(config: VortexL1Config)(implicit p: Parameters)
val (upstream, _) = coresideNode.in(0)
val (downstream, _) = vxCacheFetchNode.out(0)
// Make sure the outgoing edge of this passthrough has enough sourceIds
// that encompasses the core-side incoming edge's. This is an unfortunate
// hack due to not doing proper param negotiations across disconnected
// Diplomacy graphs.
// println(s"${upstream.params.sourceBits} <= ${downstream.params.sourceBits}")
require(upstream.params.sourceBits <= downstream.params.sourceBits)
downstream.a <> upstream.a
upstream.d <> downstream.d
}
@@ -197,13 +205,17 @@ class VortexBankImp(
outer: VortexBank,
config: VortexL1Config
) extends LazyModuleImp(outer) {
val (tlInFromCoal, _) = outer.coresideNode.in.head
val coreTagWidth = tlInFromCoal.a.bits.source.getWidth
val coreTagWidthPlusSize = coreTagWidth + log2Ceil(config.inputSize)
val vxCache = Module(
new VX_cache_top(
WORD_SIZE = config.inputSize,
// distribute total size across numBanks
CACHE_SIZE = config.cacheSize / config.numBanks,
CACHE_LINE_SIZE = config.cacheLineSize,
CORE_TAG_WIDTH = config.coreTagPlusSizeWidth,
CORE_TAG_WIDTH = coreTagWidthPlusSize,
MSHR_SIZE = config.mshrSize
)
);
@@ -232,7 +244,7 @@ class VortexBankImp(
class ReadReqInfo(config: VortexL1Config) extends Bundle {
val size = UInt(log2Ceil(4).W + 1)
val id = UInt(config.coreTagWidth.W)
val id = UInt(coreTagWidth.W)
}
val coreWriteReqQueue = Module(
@@ -247,8 +259,6 @@ class VortexBankImp(
// Translate TL request from Coalescer to requests for VX_cache
def TLReq2VXReq = {
val (tlInFromCoal, _) = outer.coresideNode.in.head
// coal -> vxCache
tlInFromCoal.a.ready :=
vxCache.io.core_req_ready && coreWriteReqQueue.io.enq.ready // not optimal
@@ -269,13 +279,9 @@ class VortexBankImp(
readReqInfo.id := tlInFromCoal.a.bits.source
readReqInfo.size := tlInFromCoal.a.bits.size
assert(readReqInfo.id.getWidth == tlInFromCoal.a.bits.source.getWidth,
s"id width mismatch; coalescer ${tlInFromCoal.a.bits.source.getWidth}, cache ${readReqInfo.id.getWidth}")
s"id width mismatch; core-side ${tlInFromCoal.a.bits.source.getWidth}, cache-side ${readReqInfo.id.getWidth}")
assert(readReqInfo.size.getWidth == tlInFromCoal.a.bits.size.getWidth,
s"size width mismatch; coalescer ${tlInFromCoal.a.bits.size.getWidth}, cache ${readReqInfo.size.getWidth}")
assert(readReqInfo.id.getWidth == tlInFromCoal.a.bits.source.getWidth,
s"id width mismatch; coalescer ${tlInFromCoal.a.bits.source.getWidth}, cache ${readReqInfo.id.getWidth}")
assert(readReqInfo.size.getWidth == tlInFromCoal.a.bits.size.getWidth,
s"size width mismatch; coalescer ${tlInFromCoal.a.bits.size.getWidth}, cache ${readReqInfo.size.getWidth}")
s"size width mismatch; core-side ${tlInFromCoal.a.bits.size.getWidth}, cache-side ${readReqInfo.size.getWidth}")
// ignore param, size, corrupt
vxCache.io.core_req_tag := readReqInfo.asTypeOf(vxCache.io.core_req_tag)

View File

@@ -31,7 +31,7 @@ class WithRadianceCores(
useVxCache: Boolean
) extends Config((site, _, up) => {
case TilesLocated(`location`) => {
val prev = up(TilesLocated(`location`), site)
val prev = up(TilesLocated(`location`))
val idOffset = prev.size
val vortex = RadianceTileParams(
core = VortexCoreParams(fpu = None),
@@ -76,7 +76,7 @@ class WithRadianceGemmini(location: HierarchicalLocation,
crossing: RocketCrossingParams,
dim: Int, accSizeInKB: Int) extends Config((site, _, up) => {
case TilesLocated(`location`) => {
val prev = up(TilesLocated(`location`), site)
val prev = up(TilesLocated(`location`))
val idOffset = prev.size
if (idOffset == 0) {
println("******WARNING****** gemmini tile id is 0! radiance tiles in the same cluster needs to be before gemmini")
@@ -141,7 +141,7 @@ class WithFuzzerCores(
useVxCache: Boolean
) extends Config((site, _, up) => {
case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site)
val prev = up(TilesLocated(InSubsystem))
val idOffset = prev.size
val fuzzer = FuzzerTileParams(
core = VortexCoreParams(fpu = None),
@@ -176,7 +176,7 @@ class WithRadianceCluster(
class WithSimtConfig(nWarps: Int = 4, nCoreLanes: Int = 4, nMemLanes: Int = 4, nSrcIds: Int = 8)
extends Config((site, _, up) => {
case SIMTCoreKey => {
Some(up(SIMTCoreKey, site).getOrElse(SIMTCoreParams()).copy(
Some(up(SIMTCoreKey).getOrElse(SIMTCoreParams()).copy(
nWarps = nWarps,
nCoreLanes = nCoreLanes,
nMemLanes = nMemLanes,
@@ -198,11 +198,11 @@ extends Config((site, _, _) => {
class WithPriorityCoalXbar extends Config((site, _, up) => {
case CoalXbarKey => {
Some(up(CoalXbarKey, site).getOrElse(CoalXbarParam))
Some(up(CoalXbarKey).getOrElse(CoalXbarParam))
}
})
class WithVortexL1Banks(nBanks: Int = 4) extends Config ((site, _, up) => {
class WithVortexL1Banks(nBanks: Int = 4) extends Config ((site, here, up) => {
case VortexL1Key => {
Some(defaultVortexL1Config.copy(
numBanks = nBanks,
@@ -210,10 +210,6 @@ class WithVortexL1Banks(nBanks: Int = 4) extends Config ((site, _, up) => {
cacheLineSize = up(SIMTCoreKey).get.nMemLanes * 4,
memSideSourceIds = 16,
mshrSize = 16,
coreTagWidth = log2Ceil(up(SIMTCoreKey).get.nSrcIds.max(up(CoalescerKey) match {
case Some(key) => key.numNewSrcIds
case None => 0
})) + log2Ceil(up(SIMTCoreKey).get.nMemLanes) + 1
))
}
})
@@ -224,7 +220,7 @@ class WithVortexL1Banks(nBanks: Int = 4) extends Config ((site, _, up) => {
// to e.g. compare waveforms.
class WithCoalescer(nNewSrcIds: Int = 8, enable : Boolean = true) extends Config((site, _, up) => {
case CoalescerKey => {
val (nLanes, numOldSrcIds) = up(SIMTCoreKey, site) match {
val (nLanes, numOldSrcIds) = up(SIMTCoreKey) match {
case Some(param) => (param.nMemLanes, param.nSrcIds)
case None => (1,1)
}
@@ -236,7 +232,7 @@ class WithCoalescer(nNewSrcIds: Int = 8, enable : Boolean = true) extends Config
// If instantiating L1 cache, the maximum coalescing size should match the
// cache line size
val maxCoalSizeInBytes = up(VortexL1Key, site) match {
val maxCoalSizeInBytes = up(VortexL1Key) match {
case Some(param) => param.inputSize
case None => sbusWidthInBytes
}
@@ -261,7 +257,7 @@ class WithNCustomSmallRocketCores(
crossing: RocketCrossingParams = RocketCrossingParams()
) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site)
val prev = up(TilesLocated(InSubsystem))
val idOffset = overrideIdOffset.getOrElse(prev.size)
val med = RocketTileParams(
core = RocketCoreParams(fpu = None),
@@ -295,7 +291,7 @@ class WithNCustomSmallRocketCores(
class WithExtGPUMem(address: BigInt = BigInt("0x100000000", 16),
size: BigInt = 0x80000000) extends Config((site, here, up) => {
case GPUMemory() => Some(GPUMemParams(address, size))
case ExtMem => up(ExtMem, site).map(x => {
case ExtMem => up(ExtMem).map(x => {
val gap = address - x.master.base - x.master.size
x.copy(master = x.master.copy(size = x.master.size + gap + size))
})

View File

@@ -7,8 +7,8 @@ import chisel3._
import chisel3.experimental.AffectsChiselPrefix
import chisel3.util._
import freechips.rocketchip.devices.tilelink._
import org.chipsalliance.diplomacy._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.diplomacy.lazymodule.LazyModule
import freechips.rocketchip.prci.ClockSinkParameters
import freechips.rocketchip.regmapper.RegField
import freechips.rocketchip.rocket._
@@ -318,8 +318,7 @@ class RadianceTile private (
// )
val icache = LazyModule(new VortexL1Cache(vortexL1Config.copy(
numBanks = 1,
coreTagWidth = imemSourceWidth
numBanks = 1
)))
val dcache = LazyModule(new VortexL1Cache(vortexL1Config))
// imemNodes.foreach { icache.coresideNode := TLWidthWidget(4) := _ }