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.util._
import chisel3.experimental._ import chisel3.experimental._
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import org.chipsalliance.diplomacy.lazymodule.{LazyModule, LazyModuleImp}
import freechips.rocketchip.tilelink._ import freechips.rocketchip.tilelink._
import org.chipsalliance.cde.config.{Parameters, Field} import org.chipsalliance.cde.config.{Parameters, Field}
@@ -14,15 +15,11 @@ case class VortexL1Config(
numBanks: Int, numBanks: Int,
inputSize: Int, // This is the read/write granularity of the L1 cache inputSize: Int, // This is the read/write granularity of the L1 cache
cacheLineSize: Int, cacheLineSize: Int,
coreTagWidth: Int,
writeInfoReqQSize: Int, writeInfoReqQSize: Int,
mshrSize: Int, mshrSize: Int,
memSideSourceIds: Int, memSideSourceIds: Int,
uncachedAddrSets: Seq[AddressSet] uncachedAddrSets: Seq[AddressSet]
) { ) {
def coreTagPlusSizeWidth: Int = {
log2Ceil(inputSize) + coreTagWidth
}
// NOTE: This assertion depends on the fact that the Vortex cache is // 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 // 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 // memory-side requests. Otherwise, it will append bank id to the tag as
@@ -39,7 +36,6 @@ object defaultVortexL1Config
numBanks = 4, numBanks = 4,
inputSize = 16, inputSize = 16,
cacheLineSize = 16, cacheLineSize = 16,
coreTagWidth = 8,
writeInfoReqQSize = 16, writeInfoReqQSize = 16,
mshrSize = 8, mshrSize = 8,
memSideSourceIds = 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 // Master node to downstream
val clientParam = Seq( val clientParam = Seq(
TLMasterPortParameters.v1( TLMasterPortParameters.v1(
clients = Seq( clients = Seq(
TLMasterParameters.v1( TLMasterParameters.v1(
name = "VortexBankPassthrough", name = "VortexBankPassthrough",
sourceId = IdRange(0, 1 << config.coreTagWidth), sourceId = IdRange(0, 1 << sourceWidth),
supportsProbe = TransferSizes(1, config.cacheLineSize), supportsProbe = TransferSizes(1, config.cacheLineSize),
supportsGet = TransferSizes(1, config.cacheLineSize), supportsGet = TransferSizes(1, config.cacheLineSize),
supportsPutFull = 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 (upstream, _) = coresideNode.in(0)
val (downstream, _) = vxCacheFetchNode.out(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 downstream.a <> upstream.a
upstream.d <> downstream.d upstream.d <> downstream.d
} }
@@ -197,13 +205,17 @@ class VortexBankImp(
outer: VortexBank, outer: VortexBank,
config: VortexL1Config config: VortexL1Config
) extends LazyModuleImp(outer) { ) 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( val vxCache = Module(
new VX_cache_top( new VX_cache_top(
WORD_SIZE = config.inputSize, WORD_SIZE = config.inputSize,
// distribute total size across numBanks // distribute total size across numBanks
CACHE_SIZE = config.cacheSize / config.numBanks, CACHE_SIZE = config.cacheSize / config.numBanks,
CACHE_LINE_SIZE = config.cacheLineSize, CACHE_LINE_SIZE = config.cacheLineSize,
CORE_TAG_WIDTH = config.coreTagPlusSizeWidth, CORE_TAG_WIDTH = coreTagWidthPlusSize,
MSHR_SIZE = config.mshrSize MSHR_SIZE = config.mshrSize
) )
); );
@@ -232,7 +244,7 @@ class VortexBankImp(
class ReadReqInfo(config: VortexL1Config) extends Bundle { class ReadReqInfo(config: VortexL1Config) extends Bundle {
val size = UInt(log2Ceil(4).W + 1) val size = UInt(log2Ceil(4).W + 1)
val id = UInt(config.coreTagWidth.W) val id = UInt(coreTagWidth.W)
} }
val coreWriteReqQueue = Module( val coreWriteReqQueue = Module(
@@ -247,8 +259,6 @@ class VortexBankImp(
// Translate TL request from Coalescer to requests for VX_cache // Translate TL request from Coalescer to requests for VX_cache
def TLReq2VXReq = { def TLReq2VXReq = {
val (tlInFromCoal, _) = outer.coresideNode.in.head
// coal -> vxCache // coal -> vxCache
tlInFromCoal.a.ready := tlInFromCoal.a.ready :=
vxCache.io.core_req_ready && coreWriteReqQueue.io.enq.ready // not optimal vxCache.io.core_req_ready && coreWriteReqQueue.io.enq.ready // not optimal
@@ -269,13 +279,9 @@ class VortexBankImp(
readReqInfo.id := tlInFromCoal.a.bits.source readReqInfo.id := tlInFromCoal.a.bits.source
readReqInfo.size := tlInFromCoal.a.bits.size readReqInfo.size := tlInFromCoal.a.bits.size
assert(readReqInfo.id.getWidth == tlInFromCoal.a.bits.source.getWidth, 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, 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}")
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}")
// ignore param, size, corrupt // ignore param, size, corrupt
vxCache.io.core_req_tag := readReqInfo.asTypeOf(vxCache.io.core_req_tag) vxCache.io.core_req_tag := readReqInfo.asTypeOf(vxCache.io.core_req_tag)

View File

@@ -31,7 +31,7 @@ class WithRadianceCores(
useVxCache: Boolean useVxCache: Boolean
) extends Config((site, _, up) => { ) extends Config((site, _, up) => {
case TilesLocated(`location`) => { case TilesLocated(`location`) => {
val prev = up(TilesLocated(`location`), site) val prev = up(TilesLocated(`location`))
val idOffset = prev.size val idOffset = prev.size
val vortex = RadianceTileParams( val vortex = RadianceTileParams(
core = VortexCoreParams(fpu = None), core = VortexCoreParams(fpu = None),
@@ -76,7 +76,7 @@ class WithRadianceGemmini(location: HierarchicalLocation,
crossing: RocketCrossingParams, crossing: RocketCrossingParams,
dim: Int, accSizeInKB: Int) extends Config((site, _, up) => { dim: Int, accSizeInKB: Int) extends Config((site, _, up) => {
case TilesLocated(`location`) => { case TilesLocated(`location`) => {
val prev = up(TilesLocated(`location`), site) val prev = up(TilesLocated(`location`))
val idOffset = prev.size val idOffset = prev.size
if (idOffset == 0) { if (idOffset == 0) {
println("******WARNING****** gemmini tile id is 0! radiance tiles in the same cluster needs to be before gemmini") 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 useVxCache: Boolean
) extends Config((site, _, up) => { ) extends Config((site, _, up) => {
case TilesLocated(InSubsystem) => { case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site) val prev = up(TilesLocated(InSubsystem))
val idOffset = prev.size val idOffset = prev.size
val fuzzer = FuzzerTileParams( val fuzzer = FuzzerTileParams(
core = VortexCoreParams(fpu = None), core = VortexCoreParams(fpu = None),
@@ -176,7 +176,7 @@ class WithRadianceCluster(
class WithSimtConfig(nWarps: Int = 4, nCoreLanes: Int = 4, nMemLanes: Int = 4, nSrcIds: Int = 8) class WithSimtConfig(nWarps: Int = 4, nCoreLanes: Int = 4, nMemLanes: Int = 4, nSrcIds: Int = 8)
extends Config((site, _, up) => { extends Config((site, _, up) => {
case SIMTCoreKey => { case SIMTCoreKey => {
Some(up(SIMTCoreKey, site).getOrElse(SIMTCoreParams()).copy( Some(up(SIMTCoreKey).getOrElse(SIMTCoreParams()).copy(
nWarps = nWarps, nWarps = nWarps,
nCoreLanes = nCoreLanes, nCoreLanes = nCoreLanes,
nMemLanes = nMemLanes, nMemLanes = nMemLanes,
@@ -198,11 +198,11 @@ extends Config((site, _, _) => {
class WithPriorityCoalXbar extends Config((site, _, up) => { class WithPriorityCoalXbar extends Config((site, _, up) => {
case CoalXbarKey => { 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 => { case VortexL1Key => {
Some(defaultVortexL1Config.copy( Some(defaultVortexL1Config.copy(
numBanks = nBanks, numBanks = nBanks,
@@ -210,10 +210,6 @@ class WithVortexL1Banks(nBanks: Int = 4) extends Config ((site, _, up) => {
cacheLineSize = up(SIMTCoreKey).get.nMemLanes * 4, cacheLineSize = up(SIMTCoreKey).get.nMemLanes * 4,
memSideSourceIds = 16, memSideSourceIds = 16,
mshrSize = 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. // to e.g. compare waveforms.
class WithCoalescer(nNewSrcIds: Int = 8, enable : Boolean = true) extends Config((site, _, up) => { class WithCoalescer(nNewSrcIds: Int = 8, enable : Boolean = true) extends Config((site, _, up) => {
case CoalescerKey => { case CoalescerKey => {
val (nLanes, numOldSrcIds) = up(SIMTCoreKey, site) match { val (nLanes, numOldSrcIds) = up(SIMTCoreKey) match {
case Some(param) => (param.nMemLanes, param.nSrcIds) case Some(param) => (param.nMemLanes, param.nSrcIds)
case None => (1,1) 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 // If instantiating L1 cache, the maximum coalescing size should match the
// cache line size // cache line size
val maxCoalSizeInBytes = up(VortexL1Key, site) match { val maxCoalSizeInBytes = up(VortexL1Key) match {
case Some(param) => param.inputSize case Some(param) => param.inputSize
case None => sbusWidthInBytes case None => sbusWidthInBytes
} }
@@ -261,7 +257,7 @@ class WithNCustomSmallRocketCores(
crossing: RocketCrossingParams = RocketCrossingParams() crossing: RocketCrossingParams = RocketCrossingParams()
) extends Config((site, here, up) => { ) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => { case TilesLocated(InSubsystem) => {
val prev = up(TilesLocated(InSubsystem), site) val prev = up(TilesLocated(InSubsystem))
val idOffset = overrideIdOffset.getOrElse(prev.size) val idOffset = overrideIdOffset.getOrElse(prev.size)
val med = RocketTileParams( val med = RocketTileParams(
core = RocketCoreParams(fpu = None), core = RocketCoreParams(fpu = None),
@@ -295,7 +291,7 @@ class WithNCustomSmallRocketCores(
class WithExtGPUMem(address: BigInt = BigInt("0x100000000", 16), class WithExtGPUMem(address: BigInt = BigInt("0x100000000", 16),
size: BigInt = 0x80000000) extends Config((site, here, up) => { size: BigInt = 0x80000000) extends Config((site, here, up) => {
case GPUMemory() => Some(GPUMemParams(address, size)) 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 val gap = address - x.master.base - x.master.size
x.copy(master = x.master.copy(size = x.master.size + gap + 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.experimental.AffectsChiselPrefix
import chisel3.util._ import chisel3.util._
import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.devices.tilelink._
import org.chipsalliance.diplomacy._
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import org.chipsalliance.diplomacy.lazymodule.LazyModule
import freechips.rocketchip.prci.ClockSinkParameters import freechips.rocketchip.prci.ClockSinkParameters
import freechips.rocketchip.regmapper.RegField import freechips.rocketchip.regmapper.RegField
import freechips.rocketchip.rocket._ import freechips.rocketchip.rocket._
@@ -318,8 +318,7 @@ class RadianceTile private (
// ) // )
val icache = LazyModule(new VortexL1Cache(vortexL1Config.copy( val icache = LazyModule(new VortexL1Cache(vortexL1Config.copy(
numBanks = 1, numBanks = 1
coreTagWidth = imemSourceWidth
))) )))
val dcache = LazyModule(new VortexL1Cache(vortexL1Config)) val dcache = LazyModule(new VortexL1Cache(vortexL1Config))
// imemNodes.foreach { icache.coresideNode := TLWidthWidget(4) := _ } // imemNodes.foreach { icache.coresideNode := TLWidthWidget(4) := _ }