From d0ae08758731069db82d7f8b8f9ddf336404f375 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 6 Mar 2017 21:35:45 -0800 Subject: [PATCH] rocket: allow scratchpad address to be configurable (#570) --- src/main/scala/coreplex/Configs.scala | 42 +++++++++++-------- src/main/scala/rocket/DCache.scala | 1 - src/main/scala/rocket/HellaCache.scala | 29 +++++++++---- src/main/scala/rocket/ICache.scala | 3 +- .../scala/rocket/ScratchpadSlavePort.scala | 10 ++--- src/main/scala/rocketchip/Configs.scala | 30 ++++++++++--- src/main/scala/tile/BaseTile.scala | 3 +- src/main/scala/tile/L1Cache.scala | 3 +- 8 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index e231c848..e67f4117 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -35,9 +35,17 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { class WithNBigCores(n: Int) extends Config((site, here, up) => { case RocketTilesKey => { val big = RocketTileParams( - core = RocketCoreParams(mulDiv = Some(MulDivParams(mulUnroll = 8, mulEarlyOut = true, divEarlyOut = true))), - dcache = Some(DCacheParams(rowBits = site(L1toL2Config).beatBytes*8, nMSHRs = 2)), - icache = Some(ICacheParams(rowBits = site(L1toL2Config).beatBytes*8))) + core = RocketCoreParams(mulDiv = Some(MulDivParams( + mulUnroll = 8, + mulEarlyOut = true, + divEarlyOut = true))), + dcache = Some(DCacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + nMSHRs = 2, + blockBytes = site(CacheBlockBytes))), + icache = Some(ICacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + blockBytes = site(CacheBlockBytes)))) List.fill(n)(big) ++ up(RocketTilesKey, site) } }) @@ -47,8 +55,19 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => { val small = RocketTileParams( core = RocketCoreParams(useVM = false, fpu = None), btb = None, - dcache = Some(DCacheParams(rowBits = site(L1toL2Config).beatBytes*8, nSets = 64, nWays = 1, nTLBEntries = 4, nMSHRs = 0)), - icache = Some(ICacheParams(rowBits = site(L1toL2Config).beatBytes*8, nSets = 64, nWays = 1, nTLBEntries = 4))) + dcache = Some(DCacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + nSets = 64, + nWays = 1, + nTLBEntries = 4, + nMSHRs = 0, + blockBytes = site(CacheBlockBytes))), + icache = Some(ICacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + nSets = 64, + nWays = 1, + nTLBEntries = 4, + blockBytes = site(CacheBlockBytes)))) List.fill(n)(small) ++ up(RocketTilesKey, site) } }) @@ -89,19 +108,6 @@ class WithCacheBlockBytes(linesize: Int) extends Config((site, here, up) => { case CacheBlockBytes => linesize }) -/** Warning: applies only to the most recently added tile. - * TODO: For now, there can only be a single scratchpad in the design - * because its address is hardcoded. - */ -class WithDataScratchpad(size: Int) extends Config((site, here, up) => { - case RocketTilesKey => { - val prev = up(RocketTilesKey, site) - prev.head.copy( - dcache = prev.head.dcache.map(_.copy(nSets = size / site(CacheBlockBytes))), - dataScratchpadBytes = size) +: prev.tail - } -}) - class WithL2Cache extends Config(Parameters.empty) // TODO: re-add L2 class WithL2Capacity(size_kb: Int) extends Config(Parameters.empty) // TODO: re-add L2 class WithNL2Ways(n: Int) extends Config(Parameters.empty) // TODO: re-add L2 diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 8832fca1..94d8b4a9 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -116,7 +116,6 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { val s1_victim_way = Wire(init = replacer.way) val (s1_hit_way, s1_hit_state, s1_victim_meta) = if (usingDataScratchpad) { - require(nWays == 1) metaWriteArb.io.out.ready := true metaReadArb.io.out.ready := !metaWriteArb.io.out.valid val inScratchpad = outer.scratch().map(_.contains(s1_paddr)).getOrElse(Bool(false)) diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index ac8d8a8f..4917770f 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -24,12 +24,22 @@ case class DCacheParams( nMSHRs: Int = 1, nSDQ: Int = 17, nRPQ: Int = 16, - nMMIOs: Int = 1) extends L1CacheParams { + nMMIOs: Int = 1, + blockBytes: Int = 64, + scratch: Option[BigInt] = None) extends L1CacheParams { + + def dataScratchpadBytes: Int = scratch.map(_ => nSets*blockBytes).getOrElse(0) + def replacement = new RandomReplacement(nWays) + + require((!scratch.isDefined || nWays == 1), + "Scratchpad only allowed in direct-mapped cache.") + require((!scratch.isDefined || nMSHRs == 0), + "Scratchpad only allowed in blocking cache.") + require(isPow2(nSets), s"nSets($nSets) must be pow2") } -trait HasL1HellaCacheParameters extends HasL1CacheParameters - with HasCoreParameters { +trait HasL1HellaCacheParameters extends HasL1CacheParameters with HasCoreParameters { val cacheParams = tileParams.dcache.get val cfg = cacheParams @@ -50,9 +60,8 @@ trait HasL1HellaCacheParameters extends HasL1CacheParameters def lrscCycles = 32 // ISA requires 16-insn LRSC sequences to succeed def nIOMSHRs = cacheParams.nMMIOs def maxUncachedInFlight = cacheParams.nMMIOs - def dataScratchpadSize = tileParams.dataScratchpadBytes + def dataScratchpadSize = cacheParams.dataScratchpadBytes - require(isPow2(nSets), s"nSets($nSets) must be pow2") require(rowBits >= coreDataBits, s"rowBits($rowBits) < coreDataBits($coreDataBits)") // TODO should rowBits even be seperably specifiable? require(rowBits == cacheDataBits, s"rowBits($rowBits) != cacheDataBits($cacheDataBits)") @@ -123,9 +132,13 @@ class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) { abstract class HellaCache(implicit p: Parameters) extends LazyModule { private val cfg = p(TileKey).dcache.get - val node = TLClientNode(TLClientParameters( - sourceId = IdRange(0, cfg.nMSHRs + cfg.nMMIOs), - supportsProbe = TransferSizes(1, p(CacheBlockBytes)))) + val node = TLClientNode(cfg.scratch.map { _ => + TLClientParameters(sourceId = IdRange(0, cfg.nMMIOs)) + } getOrElse { + TLClientParameters( + sourceId = IdRange(0, cfg.nMSHRs+cfg.nMMIOs), + supportsProbe = TransferSizes(1, cfg.blockBytes)) + }) val module: HellaCacheModule } diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index aed5e7b9..9df237d1 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -19,7 +19,8 @@ case class ICacheParams( nTLBEntries: Int = 8, cacheIdBits: Int = 0, splitMetadata: Boolean = false, - ecc: Option[Code] = None) extends L1CacheParams { + ecc: Option[Code] = None, + blockBytes: Int = 64) extends L1CacheParams { def replacement = new RandomReplacement(nWays) } diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 3c5a9794..0cf50a25 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -13,12 +13,12 @@ import uncore.tilelink2._ import uncore.util._ import util._ -class ScratchpadSlavePort(sizeBytes: Int)(implicit p: Parameters) extends LazyModule +class ScratchpadSlavePort(address: AddressSet)(implicit p: Parameters) extends LazyModule with HasCoreParameters { val device = new MemoryDevice val node = TLManagerNode(Seq(TLManagerPortParameters( Seq(TLManagerParameters( - address = List(AddressSet(0x80000000L, BigInt(sizeBytes-1))), + address = List(address), resources = device.reg, regionType = RegionType.UNCACHED, executable = true, @@ -110,9 +110,9 @@ class ScratchpadSlavePort(sizeBytes: Int)(implicit p: Parameters) extends LazyMo trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { val module: CanHaveScratchpadModule - val sizeBytes = tileParams.dataScratchpadBytes + val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s => + LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1))))) val slaveNode = TLInputNode() - val scratch = if (sizeBytes > 0) Some(LazyModule(new ScratchpadSlavePort(sizeBytes))) else None scratch foreach { lm => lm.node := TLFragmenter(p(XLen)/8, p(CacheBlockBytes))(slaveNode) } @@ -123,7 +123,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { finalNode.get.address(0) } - nDCachePorts += (sizeBytes > 0).toInt + nDCachePorts += (scratch.isDefined).toInt } trait CanHaveScratchpadBundle extends HasHellaCacheBundle with HasICacheFrontendBundle { diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 1c975c98..e3f8fe57 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -18,6 +18,7 @@ import scala.collection.mutable.{LinkedHashSet, ListBuffer} import scala.collection.immutable.HashMap import DefaultTestSuites._ import config._ +import tile.XLen class BasePlatformConfig extends Config((site, here, up) => { // DTS descriptive parameters @@ -99,10 +100,31 @@ class HeterogeneousDualCoreConfig extends Config( new WithNSmallCores(1) ++ new WithNBigCores(1) ++ new WithL2Cache ++ new BaseConfig) class TinyConfig extends Config( - new WithScratchpad ++ - new WithRV32 ++ + new WithNMemoryChannels(0) ++ new WithStatelessBridge ++ - new WithNSmallCores(1) ++ new BaseConfig) + new BaseConfig().alter((site, here, up) => { + case XLen => 32 + case RocketTilesKey => Seq( + RocketTileParams( + core = RocketCoreParams( + useVM = false, + fpu = None, + mulDiv = Some(MulDivParams(mulUnroll = 8))), + btb = None, + dcache = Some(DCacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + nSets = 256, // 16Kb scratchpad + nWays = 1, + nTLBEntries = 4, + nMSHRs = 0, + blockBytes = site(CacheBlockBytes), + scratch = Some(0x80000000L))), + icache = Some(ICacheParams( + rowBits = site(L1toL2Config).beatBytes*8, + nSets = 64, + nWays = 1, + nTLBEntries = 4, + blockBytes = site(CacheBlockBytes)))))})) /* Composable partial function Configs to set individual parameters */ @@ -152,6 +174,4 @@ class WithTimebase(hertz: BigInt) extends Config((site, here, up) => { case DTSTimebase => hertz }) -class WithScratchpad extends Config(new WithNMemoryChannels(0) ++ new WithDataScratchpad(16384)) - class DefaultFPGASmallConfig extends Config(new WithNSmallCores(1) ++ new DefaultFPGAConfig) diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index f39da677..3b72d40d 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -18,7 +18,6 @@ trait TileParams { val dcache: Option[DCacheParams] val rocc: Seq[RoCCParams] val btb: Option[BTBParams] - val dataScratchpadBytes: Int } trait HasTileParameters { @@ -31,7 +30,7 @@ trait HasTileParameters { val usingRoCC = !tileParams.rocc.isEmpty val usingBTB = tileParams.btb.isDefined && tileParams.btb.get.nEntries > 0 val usingPTW = usingVM - val usingDataScratchpad = tileParams.dcache.isDefined && tileParams.dataScratchpadBytes > 0 + val usingDataScratchpad = tileParams.dcache.flatMap(_.scratch).isDefined def dcacheArbPorts = 1 + usingVM.toInt + usingDataScratchpad.toInt + tileParams.rocc.size } diff --git a/src/main/scala/tile/L1Cache.scala b/src/main/scala/tile/L1Cache.scala index 2d8d7734..54e1cdee 100644 --- a/src/main/scala/tile/L1Cache.scala +++ b/src/main/scala/tile/L1Cache.scala @@ -17,13 +17,14 @@ trait L1CacheParams { def nTLBEntries: Int def splitMetadata: Boolean def ecc: Option[Code] + def blockBytes: Int } trait HasL1CacheParameters { implicit val p: Parameters val cacheParams: L1CacheParams - def cacheBlockBytes = p(CacheBlockBytes) + def cacheBlockBytes = cacheParams.blockBytes def lgCacheBlockBytes = log2Up(cacheBlockBytes) def nSets = cacheParams.nSets def blockOffBits = lgCacheBlockBytes