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:
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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) := _ }
|
||||||
|
|||||||
Reference in New Issue
Block a user