From c65c255815c3729ff58306acf8643aab53329045 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 22 Nov 2016 10:53:44 -0800 Subject: [PATCH 01/21] [coreplex] TileId moved to groundtest --- src/main/scala/groundtest/Coreplex.scala | 3 ++- src/main/scala/rocket/tile.scala | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 23529037..1abb2a32 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -6,9 +6,10 @@ import diplomacy._ import coreplex._ import uncore.devices.NTiles import uncore.tilelink2._ -import rocket.TileId import uncore.tilelink.TLId +case object TileId extends Field[Int] + class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { val tiles = List.tabulate(p(NTiles)) { i => LazyModule(new GroundTestTile()(p.alterPartial({ diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index e0b7a585..259ada1b 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -14,7 +14,6 @@ import config._ import scala.collection.mutable.ListBuffer case object BuildRoCC extends Field[Seq[RoccParameters]] -case object TileId extends Field[Int] case class RoccParameters( opcodes: OpcodeSet, @@ -30,7 +29,6 @@ class RocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule { val dcacheParams = coreParams.alterPartial({ case CacheName => CacheName("L1D") case TLId => "L1toL2" - case TileId => tileId // TODO using this messes with Heirarchical P&R: change to io.hartid? }) val icacheParams = coreParams.alterPartial({ case CacheName => CacheName("L1I") From 16d0f522b00a2fec0a510dfa790008fc07038857 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 22 Nov 2016 11:05:30 -0800 Subject: [PATCH 02/21] [tracegen] filter seed report --- scripts/tracegen.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/tracegen.py b/scripts/tracegen.py index bc214e6c..10c3d1bb 100755 --- a/scripts/tracegen.py +++ b/scripts/tracegen.py @@ -52,6 +52,8 @@ def main(): numFinished = numFinished + 1 if numFinished == total: break + elif line[0:12] == "using random": + continue else: print line, From dae6772624b6f15aa3327b94f6d51fe6ddeb4da4 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 22 Nov 2016 11:50:41 -0800 Subject: [PATCH 03/21] factor out common cache subcomponents into uncore.util --- src/main/scala/coreplex/Configs.scala | 1 + src/main/scala/groundtest/CacheFillTest.scala | 2 +- src/main/scala/groundtest/Configs.scala | 1 + src/main/scala/groundtest/Regression.scala | 2 +- src/main/scala/groundtest/Tile.scala | 2 +- src/main/scala/rocket/Dcache.scala | 1 - src/main/scala/rocket/HellaCache.scala | 2 +- src/main/scala/rocket/NBDcache.scala | 1 - src/main/scala/rocket/btb.scala | 2 +- src/main/scala/rocket/ptw.scala | 2 +- src/main/scala/rocket/rocc.scala | 2 +- src/main/scala/rocket/rocket.scala | 2 +- src/main/scala/rocket/tile.scala | 2 +- src/main/scala/rocket/tlb.scala | 3 +- .../agents/{Cache.scala => L2Cache.scala} | 174 +---------------- src/main/scala/uncore/util/Cache.scala | 180 ++++++++++++++++++ .../scala/uncore/{agents => util}/Ecc.scala | 2 +- 17 files changed, 194 insertions(+), 187 deletions(-) rename src/main/scala/uncore/agents/{Cache.scala => L2Cache.scala} (87%) create mode 100644 src/main/scala/uncore/util/Cache.scala rename src/main/scala/uncore/{agents => util}/Ecc.scala (99%) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 13986aa0..01a34c53 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -11,6 +11,7 @@ import uncore.coherence._ import uncore.agents._ import uncore.devices._ import uncore.converters._ +import uncore.util._ import rocket._ import util._ import util.ConfigUtils._ diff --git a/src/main/scala/groundtest/CacheFillTest.scala b/src/main/scala/groundtest/CacheFillTest.scala index 685bc8bc..446db059 100644 --- a/src/main/scala/groundtest/CacheFillTest.scala +++ b/src/main/scala/groundtest/CacheFillTest.scala @@ -3,7 +3,7 @@ package groundtest import Chisel._ import uncore.tilelink._ import uncore.constants._ -import uncore.agents._ +import uncore.util._ import util._ import config._ diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index b0727f24..02dc603f 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -6,6 +6,7 @@ import diplomacy._ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ +import uncore.util._ import uncore.devices.NTiles import junctions._ import config._ diff --git a/src/main/scala/groundtest/Regression.scala b/src/main/scala/groundtest/Regression.scala index 6652c583..3d89ad7b 100644 --- a/src/main/scala/groundtest/Regression.scala +++ b/src/main/scala/groundtest/Regression.scala @@ -3,7 +3,7 @@ package groundtest import Chisel._ import uncore.tilelink._ import uncore.constants._ -import uncore.agents._ +import uncore.util._ import util._ import rocket._ import rocketchip._ diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 5f002844..255f531d 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -3,7 +3,7 @@ package groundtest import Chisel._ import rocket._ import uncore.tilelink._ -import uncore.agents.CacheName +import uncore.util.CacheName import uncore.tilelink2._ import rocketchip.ExtMem import diplomacy._ diff --git a/src/main/scala/rocket/Dcache.scala b/src/main/scala/rocket/Dcache.scala index 5027e8c4..8b999b0d 100644 --- a/src/main/scala/rocket/Dcache.scala +++ b/src/main/scala/rocket/Dcache.scala @@ -5,7 +5,6 @@ package rocket import Chisel._ import Chisel.ImplicitConversions._ import diplomacy._ -import uncore.agents._ import uncore.constants._ import uncore.tilelink2._ import uncore.util._ diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 6a783e80..90d10b57 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -6,7 +6,7 @@ import Chisel._ import config.{Parameters, Field} import diplomacy._ import uncore.tilelink2._ -import uncore.agents._ +import uncore.util._ import uncore.constants._ import uncore.tilelink.{TLKey, TLId} import util.ParameterizedBundle diff --git a/src/main/scala/rocket/NBDcache.scala b/src/main/scala/rocket/NBDcache.scala index 5c4ecc10..ac9f770c 100644 --- a/src/main/scala/rocket/NBDcache.scala +++ b/src/main/scala/rocket/NBDcache.scala @@ -5,7 +5,6 @@ package rocket import Chisel._ import Chisel.ImplicitConversions._ import diplomacy._ -import uncore.agents._ import uncore.constants._ import uncore.tilelink._ import uncore.tilelink2._ diff --git a/src/main/scala/rocket/btb.scala b/src/main/scala/rocket/btb.scala index 98d06f04..5217478a 100644 --- a/src/main/scala/rocket/btb.scala +++ b/src/main/scala/rocket/btb.scala @@ -6,7 +6,7 @@ import Chisel._ import config._ import util._ import Chisel.ImplicitConversions._ -import uncore.agents.PseudoLRU +import uncore.util.PseudoLRU case object BtbKey extends Field[BtbParameters] diff --git a/src/main/scala/rocket/ptw.scala b/src/main/scala/rocket/ptw.scala index 60e8fa92..665a8a4e 100644 --- a/src/main/scala/rocket/ptw.scala +++ b/src/main/scala/rocket/ptw.scala @@ -3,7 +3,7 @@ package rocket import Chisel._ -import uncore.agents._ +import uncore.util.PseudoLRU import uncore.constants._ import util._ import Chisel.ImplicitConversions._ diff --git a/src/main/scala/rocket/rocc.scala b/src/main/scala/rocket/rocc.scala index 4503c984..2d2bc4ef 100644 --- a/src/main/scala/rocket/rocc.scala +++ b/src/main/scala/rocket/rocc.scala @@ -5,7 +5,7 @@ package rocket import Chisel._ import uncore.tilelink._ import uncore.constants._ -import uncore.agents.CacheName +import uncore.util.CacheName import util._ import Chisel.ImplicitConversions._ import config._ diff --git a/src/main/scala/rocket/rocket.scala b/src/main/scala/rocket/rocket.scala index 0c29cd36..e397fbed 100644 --- a/src/main/scala/rocket/rocket.scala +++ b/src/main/scala/rocket/rocket.scala @@ -4,7 +4,7 @@ package rocket import Chisel._ import uncore.devices._ -import uncore.agents.CacheName +import uncore.util.CacheName import uncore.constants._ import uncore.tilelink2._ import util._ diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 259ada1b..c0845d66 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -6,7 +6,7 @@ import Chisel._ import diplomacy._ import uncore.tilelink._ import uncore.tilelink2._ -import uncore.agents._ +import uncore.util.{CacheName, CacheBlockBytes} import uncore.converters._ import uncore.devices._ import util._ diff --git a/src/main/scala/rocket/tlb.scala b/src/main/scala/rocket/tlb.scala index 86020004..12da4628 100644 --- a/src/main/scala/rocket/tlb.scala +++ b/src/main/scala/rocket/tlb.scala @@ -8,8 +8,7 @@ import Chisel.ImplicitConversions._ import scala.math._ import config._ import diplomacy._ -import uncore.agents._ -import uncore.coherence._ +import uncore.util._ import uncore.tilelink2._ case object PgLevels extends Field[Int] diff --git a/src/main/scala/uncore/agents/Cache.scala b/src/main/scala/uncore/agents/L2Cache.scala similarity index 87% rename from src/main/scala/uncore/agents/Cache.scala rename to src/main/scala/uncore/agents/L2Cache.scala index 6f79a945..c22a1faf 100644 --- a/src/main/scala/uncore/agents/Cache.scala +++ b/src/main/scala/uncore/agents/L2Cache.scala @@ -5,186 +5,14 @@ package uncore.agents import Chisel._ import scala.reflect.ClassTag import junctions.PAddrBits -import util.ParameterizedBundle -import uncore.util.AMOALU import uncore.coherence._ import uncore.tilelink._ import uncore.constants._ import uncore.util._ import util._ -import config._ +import config.{Parameters, Field} -case class CacheConfig( - nSets: Int, - nWays: Int, - rowBits: Int, - nTLBEntries: Int, - cacheIdBits: Int, - splitMetadata: Boolean) -case class CacheName(id: String) extends Field[CacheConfig] -case object CacheName extends Field[CacheName] - -case object Replacer extends Field[() => ReplacementPolicy] -case object L2Replacer extends Field[() => SeqReplacementPolicy] -case object NPrimaryMisses extends Field[Int] -case object NSecondaryMisses extends Field[Int] -case object CacheBlockBytes extends Field[Int] -case object ECCCode extends Field[Option[Code]] case object CacheId extends Field[Int] - -trait HasCacheParameters { - implicit val p: Parameters - val cacheConfig = p(p(CacheName)) - val nSets = cacheConfig.nSets - val blockOffBits = p(CacheBlockOffsetBits) - val cacheIdBits = cacheConfig.cacheIdBits - val idxBits = log2Up(cacheConfig.nSets) - val untagBits = blockOffBits + cacheIdBits + idxBits - val tagBits = p(PAddrBits) - untagBits - val nWays = cacheConfig.nWays - val wayBits = log2Up(nWays) - val isDM = nWays == 1 - val rowBits = cacheConfig.rowBits - val rowBytes = rowBits/8 - val rowOffBits = log2Up(rowBytes) - val code = p(ECCCode).getOrElse(new IdentityCode) - val hasSplitMetadata = cacheConfig.splitMetadata -} - -abstract class CacheModule(implicit val p: Parameters) extends Module - with HasCacheParameters -abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) - with HasCacheParameters - -abstract class ReplacementPolicy { - def way: UInt - def miss: Unit - def hit: Unit -} - -class RandomReplacement(ways: Int) extends ReplacementPolicy { - private val replace = Wire(Bool()) - replace := Bool(false) - val lfsr = LFSR16(replace) - - def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0) - def miss = replace := Bool(true) - def hit = {} -} - -abstract class SeqReplacementPolicy { - def access(set: UInt): Unit - def update(valid: Bool, hit: Bool, set: UInt, way: UInt): Unit - def way: UInt -} - -class SeqRandom(n_ways: Int) extends SeqReplacementPolicy { - val logic = new RandomReplacement(n_ways) - def access(set: UInt) = { } - def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { - when (valid && !hit) { logic.miss } - } - def way = logic.way -} - -class PseudoLRU(n: Int) -{ - require(isPow2(n)) - val state_reg = Reg(Bits(width = n)) - def access(way: UInt) { - state_reg := get_next_state(state_reg,way) - } - def get_next_state(state: UInt, way: UInt) = { - var next_state = state - var idx = UInt(1,1) - for (i <- log2Up(n)-1 to 0 by -1) { - val bit = way(i) - next_state = next_state.bitSet(idx, !bit) - idx = Cat(idx, bit) - } - next_state - } - def replace = get_replace_way(state_reg) - def get_replace_way(state: Bits) = { - var idx = UInt(1,1) - for (i <- 0 until log2Up(n)) - idx = Cat(idx, state(idx)) - idx(log2Up(n)-1,0) - } -} - -class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy { - val state = SeqMem(n_sets, Bits(width = n_ways-1)) - val logic = new PseudoLRU(n_ways) - val current_state = Wire(Bits()) - val plru_way = logic.get_replace_way(current_state) - val next_state = Wire(Bits()) - - def access(set: UInt) = { - current_state := Cat(state.read(set), Bits(0, width = 1)) - } - - def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { - val update_way = Mux(hit, way, plru_way) - next_state := logic.get_next_state(current_state, update_way) - when (valid) { state.write(set, next_state(n_ways-1,1)) } - } - - def way = plru_way -} - -abstract class Metadata(implicit p: Parameters) extends CacheBundle()(p) { - val tag = Bits(width = tagBits) -} - -class MetaReadReq(implicit p: Parameters) extends CacheBundle()(p) { - val idx = Bits(width = idxBits) - val way_en = Bits(width = nWays) -} - -class MetaWriteReq[T <: Metadata](gen: T)(implicit p: Parameters) extends MetaReadReq()(p) { - val data = gen.cloneType - override def cloneType = new MetaWriteReq(gen)(p).asInstanceOf[this.type] -} - -class MetadataArray[T <: Metadata](onReset: () => T)(implicit p: Parameters) extends CacheModule()(p) { - val rstVal = onReset() - val io = new Bundle { - val read = Decoupled(new MetaReadReq).flip - val write = Decoupled(new MetaWriteReq(rstVal)).flip - val resp = Vec(nWays, rstVal.cloneType).asOutput - } - val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1))) - val rst = rst_cnt < UInt(nSets) - val waddr = Mux(rst, rst_cnt, io.write.bits.idx) - val wdata = Mux(rst, rstVal, io.write.bits.data).asUInt - val wmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.write.bits.way_en.asSInt).toBools - val rmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.read.bits.way_en.asSInt).toBools - when (rst) { rst_cnt := rst_cnt+UInt(1) } - - val metabits = rstVal.getWidth - - if (hasSplitMetadata) { - val tag_arrs = List.fill(nWays){ SeqMem(nSets, UInt(width = metabits)) } - val tag_readout = Wire(Vec(nWays,rstVal.cloneType)) - (0 until nWays).foreach { (i) => - when (rst || (io.write.valid && wmask(i))) { - tag_arrs(i).write(waddr, wdata) - } - io.resp(i) := rstVal.fromBits(tag_arrs(i).read(io.read.bits.idx, io.read.valid && rmask(i))) - } - } else { - val tag_arr = SeqMem(nSets, Vec(nWays, UInt(width = metabits))) - when (rst || io.write.valid) { - tag_arr.write(waddr, Vec.fill(nWays)(wdata), wmask) - } - io.resp := tag_arr.read(io.read.bits.idx, io.read.valid).map(rstVal.fromBits(_)) - } - - io.read.ready := !rst && !io.write.valid // so really this could be a 6T RAM - io.write.ready := !rst -} - case object L2DirectoryRepresentation extends Field[DirectoryRepresentation] trait HasOuterCacheParameters extends HasCacheParameters with HasCoherenceAgentParameters { diff --git a/src/main/scala/uncore/util/Cache.scala b/src/main/scala/uncore/util/Cache.scala new file mode 100644 index 00000000..59401e23 --- /dev/null +++ b/src/main/scala/uncore/util/Cache.scala @@ -0,0 +1,180 @@ +// See LICENSE for license details. + +package uncore.util + +import Chisel._ +import config.{Parameters, Field} +import junctions.PAddrBits +import util.ParameterizedBundle +import uncore.constants._ + +case class CacheConfig( + nSets: Int, + nWays: Int, + rowBits: Int, + nTLBEntries: Int, + cacheIdBits: Int, + splitMetadata: Boolean) +case class CacheName(id: String) extends Field[CacheConfig] +case object CacheName extends Field[CacheName] + +case object Replacer extends Field[() => ReplacementPolicy] +case object L2Replacer extends Field[() => SeqReplacementPolicy] +case object NPrimaryMisses extends Field[Int] +case object NSecondaryMisses extends Field[Int] +case object CacheBlockBytes extends Field[Int] +case object ECCCode extends Field[Option[Code]] + +trait HasCacheParameters { + implicit val p: Parameters + val cacheConfig = p(p(CacheName)) + val nSets = cacheConfig.nSets + val blockOffBits = log2Up(p(CacheBlockBytes)) + val cacheIdBits = cacheConfig.cacheIdBits + val idxBits = log2Up(cacheConfig.nSets) + val untagBits = blockOffBits + cacheIdBits + idxBits + val tagBits = p(PAddrBits) - untagBits + val nWays = cacheConfig.nWays + val wayBits = log2Up(nWays) + val isDM = nWays == 1 + val rowBits = cacheConfig.rowBits + val rowBytes = rowBits/8 + val rowOffBits = log2Up(rowBytes) + val code = p(ECCCode).getOrElse(new IdentityCode) + val hasSplitMetadata = cacheConfig.splitMetadata +} + +abstract class CacheModule(implicit val p: Parameters) extends Module + with HasCacheParameters +abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) + with HasCacheParameters + +abstract class ReplacementPolicy { + def way: UInt + def miss: Unit + def hit: Unit +} + +class RandomReplacement(ways: Int) extends ReplacementPolicy { + private val replace = Wire(Bool()) + replace := Bool(false) + val lfsr = LFSR16(replace) + + def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0) + def miss = replace := Bool(true) + def hit = {} +} + +abstract class SeqReplacementPolicy { + def access(set: UInt): Unit + def update(valid: Bool, hit: Bool, set: UInt, way: UInt): Unit + def way: UInt +} + +class SeqRandom(n_ways: Int) extends SeqReplacementPolicy { + val logic = new RandomReplacement(n_ways) + def access(set: UInt) = { } + def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { + when (valid && !hit) { logic.miss } + } + def way = logic.way +} + +class PseudoLRU(n: Int) +{ + require(isPow2(n)) + val state_reg = Reg(Bits(width = n)) + def access(way: UInt) { + state_reg := get_next_state(state_reg,way) + } + def get_next_state(state: UInt, way: UInt) = { + var next_state = state + var idx = UInt(1,1) + for (i <- log2Up(n)-1 to 0 by -1) { + val bit = way(i) + next_state = next_state.bitSet(idx, !bit) + idx = Cat(idx, bit) + } + next_state + } + def replace = get_replace_way(state_reg) + def get_replace_way(state: Bits) = { + var idx = UInt(1,1) + for (i <- 0 until log2Up(n)) + idx = Cat(idx, state(idx)) + idx(log2Up(n)-1,0) + } +} + +class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy { + val state = SeqMem(n_sets, Bits(width = n_ways-1)) + val logic = new PseudoLRU(n_ways) + val current_state = Wire(Bits()) + val plru_way = logic.get_replace_way(current_state) + val next_state = Wire(Bits()) + + def access(set: UInt) = { + current_state := Cat(state.read(set), Bits(0, width = 1)) + } + + def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { + val update_way = Mux(hit, way, plru_way) + next_state := logic.get_next_state(current_state, update_way) + when (valid) { state.write(set, next_state(n_ways-1,1)) } + } + + def way = plru_way +} + +abstract class Metadata(implicit p: Parameters) extends CacheBundle()(p) { + val tag = Bits(width = tagBits) +} + +class MetaReadReq(implicit p: Parameters) extends CacheBundle()(p) { + val idx = Bits(width = idxBits) + val way_en = Bits(width = nWays) +} + +class MetaWriteReq[T <: Metadata](gen: T)(implicit p: Parameters) extends MetaReadReq()(p) { + val data = gen.cloneType + override def cloneType = new MetaWriteReq(gen)(p).asInstanceOf[this.type] +} + +class MetadataArray[T <: Metadata](onReset: () => T)(implicit p: Parameters) extends CacheModule()(p) { + val rstVal = onReset() + val io = new Bundle { + val read = Decoupled(new MetaReadReq).flip + val write = Decoupled(new MetaWriteReq(rstVal)).flip + val resp = Vec(nWays, rstVal.cloneType).asOutput + } + val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1))) + val rst = rst_cnt < UInt(nSets) + val waddr = Mux(rst, rst_cnt, io.write.bits.idx) + val wdata = Mux(rst, rstVal, io.write.bits.data).asUInt + val wmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.write.bits.way_en.asSInt).toBools + val rmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.read.bits.way_en.asSInt).toBools + when (rst) { rst_cnt := rst_cnt+UInt(1) } + + val metabits = rstVal.getWidth + + if (hasSplitMetadata) { + val tag_arrs = List.fill(nWays){ SeqMem(nSets, UInt(width = metabits)) } + val tag_readout = Wire(Vec(nWays,rstVal.cloneType)) + (0 until nWays).foreach { (i) => + when (rst || (io.write.valid && wmask(i))) { + tag_arrs(i).write(waddr, wdata) + } + io.resp(i) := rstVal.fromBits(tag_arrs(i).read(io.read.bits.idx, io.read.valid && rmask(i))) + } + } else { + val tag_arr = SeqMem(nSets, Vec(nWays, UInt(width = metabits))) + when (rst || io.write.valid) { + tag_arr.write(waddr, Vec.fill(nWays)(wdata), wmask) + } + io.resp := tag_arr.read(io.read.bits.idx, io.read.valid).map(rstVal.fromBits(_)) + } + + io.read.ready := !rst && !io.write.valid // so really this could be a 6T RAM + io.write.ready := !rst +} + diff --git a/src/main/scala/uncore/agents/Ecc.scala b/src/main/scala/uncore/util/Ecc.scala similarity index 99% rename from src/main/scala/uncore/agents/Ecc.scala rename to src/main/scala/uncore/util/Ecc.scala index acb306b9..cfb6cd38 100644 --- a/src/main/scala/uncore/agents/Ecc.scala +++ b/src/main/scala/uncore/util/Ecc.scala @@ -1,6 +1,6 @@ // See LICENSE for license details. -package uncore.agents +package uncore.util import Chisel._ import util._ From 38c5af5bada9ad95bc5274f4616b41a2db07e766 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 23 Nov 2016 12:02:23 -0800 Subject: [PATCH 04/21] [rocket] cleanup mshr logic --- src/main/scala/rocket/NBDcache.scala | 47 ++++++++----------- .../scala/uncore/tilelink2/Metadata.scala | 20 +++++--- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/main/scala/rocket/NBDcache.scala b/src/main/scala/rocket/NBDcache.scala index ac9f770c..5a63f81c 100644 --- a/src/main/scala/rocket/NBDcache.scala +++ b/src/main/scala/rocket/NBDcache.scala @@ -175,15 +175,18 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters) val req_tag = req.addr >> untagBits val req_block_addr = (req.addr >> blockOffBits) << blockOffBits val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits) + + val new_coh = Reg(init=ClientMetadata.onReset) + val (_, shrink_param, coh_on_clear) = req.old_meta.coh.onCacheControl(M_FLUSH) + val grow_param = new_coh.onAccess(req.cmd)._2 + val coh_on_grant = new_coh.onGrant(req.cmd, io.mem_grant.bits.param) // We only accept secondary misses if we haven't yet sent an Acquire to outer memory // or if the Acquire that was sent will obtain a Grant with sufficient permissions // to let us replay this new request. I.e. we don't handle multiple outstanding // Acquires on the same block for now. - val cmd_requires_second_acquire = - req.old_meta.coh.requiresAcquireOnSecondaryMiss(req.cmd, io.req_bits.cmd) - // Track whether or not a secondary acquire will cause the coherence state - // to go from clean to dirty. - val dirties_coh = Reg(Bool()) + val (cmd_requires_second_acquire, is_hit_again, _, dirtier_coh, dirtier_cmd) = + new_coh.onSecondaryAccess(req.cmd, io.req_bits.cmd) + val states_before_refill = Seq(s_wb_req, s_wb_resp, s_meta_clear) val (_, _, refill_done, refill_address_inc) = edge.addr_inc(io.mem_grant) val sec_rdy = idx_match && @@ -196,19 +199,6 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters) rpq.io.enq.bits := io.req_bits rpq.io.deq.ready := (io.replay.ready && state === s_drain_rpq) || state === s_invalid - // TODO clean all this coh state business up - val new_coh_state = Reg(init=ClientMetadata.onReset) - val grow_param = Reg(init=UInt(0)) - val coh_on_grant = Mux(dirties_coh, - ClientMetadata.maximum, - req.old_meta.coh.onGrant(req.cmd, io.mem_grant.bits.param)) - val (is_hit, missed_param, coh_on_hit) = io.req_bits.old_meta.coh.onAccess(io.req_bits.cmd) - val (needs_wb, _, _) = io.req_bits.old_meta.coh.onCacheControl(M_FLUSH) - val (_, shrink_param, _) = req.old_meta.coh.onCacheControl(M_FLUSH) - val (hit_again, missed_again_param, _) = req.old_meta.coh.onCacheControl(io.req_bits.cmd) - val (_, _, clear_coh_state) = req.old_meta.coh.onCacheControl(M_FLUSH) - val (_, after_wb_param, _) = ClientMetadata.onReset.onAccess(req.cmd) - when (state === s_drain_rpq && !rpq.io.deq.valid) { state := s_invalid } @@ -220,14 +210,13 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters) state := s_meta_write_resp } when (state === s_refill_resp && refill_done) { + new_coh := coh_on_grant state := s_meta_write_req - new_coh_state := coh_on_grant } when (io.mem_acquire.fire()) { // s_refill_req state := s_refill_resp } when (state === s_meta_clear && io.meta_write.ready) { - grow_param := after_wb_param state := s_refill_req } when (state === s_wb_resp && io.mem_grant.valid) { @@ -240,24 +229,26 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters) //If we get a secondary miss that needs more permissions before we've sent // out the primary miss's Acquire, we can upgrade the permissions we're // going to ask for in s_refill_req - when(cmd_requires_second_acquire) { - req.cmd := io.req_bits.cmd - when(!hit_again) { grow_param := missed_again_param } + req.cmd := dirtier_cmd + when (is_hit_again) { + new_coh := dirtier_coh } - dirties_coh := dirties_coh || isWrite(io.req_bits.cmd) } when (io.req_pri_val && io.req_pri_rdy) { req := io.req_bits - dirties_coh := isWrite(io.req_bits.cmd) + val old_coh = io.req_bits.old_meta.coh + val needs_wb = old_coh.onCacheControl(M_FLUSH)._1 + val (is_hit, _, coh_on_hit) = old_coh.onAccess(io.req_bits.cmd) when (io.req_bits.tag_match) { when (is_hit) { // set dirty bit + new_coh := coh_on_hit state := s_meta_write_req - new_coh_state := coh_on_hit }.otherwise { // upgrade permissions + new_coh := old_coh state := s_refill_req - grow_param := missed_param } }.otherwise { // writback if necessary and refill + new_coh := ClientMetadata.onReset state := Mux(needs_wb, s_wb_req, s_meta_clear) } } @@ -284,7 +275,7 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters) io.meta_write.valid := state.isOneOf(s_meta_write_req, s_meta_clear) io.meta_write.bits.idx := req_idx - io.meta_write.bits.data.coh := Mux(state === s_meta_clear, clear_coh_state, new_coh_state) + io.meta_write.bits.data.coh := Mux(state === s_meta_clear, coh_on_clear, new_coh) io.meta_write.bits.data.tag := io.tag io.meta_write.bits.way_en := req.way_en diff --git a/src/main/scala/uncore/tilelink2/Metadata.scala b/src/main/scala/uncore/tilelink2/Metadata.scala index 2e23ae7b..bee18753 100644 --- a/src/main/scala/uncore/tilelink2/Metadata.scala +++ b/src/main/scala/uncore/tilelink2/Metadata.scala @@ -88,12 +88,6 @@ class ClientMetadata extends Bundle { Cat(wr, toT) -> Dirty)) } - /** Does a secondary miss on the block require another Acquire message */ - def requiresAcquireOnSecondaryMiss(first_cmd: UInt, second_cmd: UInt): Bool = { - import MemoryOpCategories._ - isWriteIntent(second_cmd) && !isWriteIntent(first_cmd) - } - /** Does this cache have permissions on this block sufficient to perform op, * and what to do next (Acquire message param or updated metadata). */ def onAccess(cmd: UInt): (Bool, UInt, ClientMetadata) = { @@ -101,6 +95,20 @@ class ClientMetadata extends Bundle { (r._1, r._2, ClientMetadata(r._2)) } + /** Does a secondary miss on the block require another Acquire message */ + def onSecondaryAccess(first_cmd: UInt, second_cmd: UInt): (Bool, Bool, UInt, ClientMetadata, UInt) = { + import MemoryOpCategories._ + val r1 = growStarter(first_cmd) + val r2 = growStarter(second_cmd) + val needs_second_acq = isWriteIntent(second_cmd) && !isWriteIntent(first_cmd) + val hit_again = r1._1 && r2._1 + val dirties = categorize(second_cmd) === wr + val biggest_grow_param = Mux(dirties, r2._2, r1._2) + val dirtiest_state = ClientMetadata(biggest_grow_param) + val dirtiest_cmd = Mux(dirties, second_cmd, first_cmd) + (needs_second_acq, hit_again, biggest_grow_param, dirtiest_state, dirtiest_cmd) + } + /** Metadata change on a returned Grant */ def onGrant(cmd: UInt, param: UInt): ClientMetadata = ClientMetadata(growFinisher(cmd, param)) From 837d207064f73088829e14639da8562ab27313d0 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 23 Nov 2016 12:18:18 -0800 Subject: [PATCH 05/21] [travis] split up groundtest into two suites --- .travis.yml | 3 ++- regression/Makefile | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ab1c95d..4e3c4905 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,8 @@ env: - SUITE=RocketSuiteA - SUITE=RocketSuiteB - SUITE=RocketSuiteC - - SUITE=GroundtestSuite + - SUITE=GroundtestSuiteA + - SUITE=GroundtestSuiteB - SUITE=UnittestSuite # blacklist private branches diff --git a/regression/Makefile b/regression/Makefile index a6322da2..45187027 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -53,10 +53,14 @@ PROJECT=rocketchip CONFIGS=DefaultL2Config TinyConfig endif -ifeq ($(SUITE),GroundtestSuite) +ifeq ($(SUITE),GroundtestSuiteA) PROJECT=groundtest -CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig FancyMemtestConfig \ - BroadcastRegressionTestConfig BufferlessRegressionTestConfig CacheRegressionTestConfig \ +CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig FancyMemtestConfig +endif + +ifeq ($(SUITE),GroundtestSuiteB) +PROJECT=groundtest +CONFIGS=BroadcastRegressionTestConfig BufferlessRegressionTestConfig CacheRegressionTestConfig \ ComparatorConfig ComparatorBufferlessConfig ComparatorL2Config ComparatorStatelessConfig endif From 4b9dc789515a8cced448d7b5280f22097820b4d2 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 15:35:53 -0800 Subject: [PATCH 06/21] rocketchip: add a parameter-controlled debug port --- src/main/scala/rocketchip/RISCVPlatform.scala | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/main/scala/rocketchip/RISCVPlatform.scala b/src/main/scala/rocketchip/RISCVPlatform.scala index 29c930c3..4b9cdb0e 100644 --- a/src/main/scala/rocketchip/RISCVPlatform.scala +++ b/src/main/scala/rocketchip/RISCVPlatform.scala @@ -11,6 +11,8 @@ import util._ import junctions.JTAGIO import coreplex._ +/// Core with JTAG for debug only + trait PeripheryJTAG extends TopNetwork { val module: PeripheryJTAGModule val coreplex: CoreplexRISCVPlatform @@ -34,6 +36,8 @@ trait PeripheryJTAGModule extends TopNetworkModule { dtm.reset := io.jtag.TRST } +/// Core with DTM for debug only + trait PeripheryDTM extends TopNetwork { val module: PeripheryDTMModule val coreplex: CoreplexRISCVPlatform @@ -52,6 +56,36 @@ trait PeripheryDTMModule extends TopNetworkModule { outer.coreplex.module.io.debug <> ToAsyncDebugBus(io.debug) } +/// Core with DTM or JTAG based on a parameter + +trait PeripheryDebug extends TopNetwork { + val module: PeripheryDebugModule + val coreplex: CoreplexRISCVPlatform +} + +trait PeripheryDebugBundle extends TopNetworkBundle { + val outer: PeripheryDebug + + val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO().flip) + val jtag = (p(IncludeJtagDTM)).option(new JTAGIO(true).flip) +} + +trait PeripheryDebugModule extends TopNetworkModule { + val outer: PeripheryDebug + val io: PeripheryDebugBundle + + io.debug.foreach { dbg => outer.coreplex.module.io.debug <> ToAsyncDebugBus(dbg) } + io.jtag.foreach { jtag => + val dtm = Module (new JtagDTMWithSync) + dtm.clock := jtag.TCK + dtm.reset := jtag.TRST + dtm.io.jtag <> jtag + outer.coreplex.module.io.debug <> dtm.io.debug + } +} + +/// Real-time clock is based on RTCPeriod relative to Top clock + trait PeripheryCounter extends TopNetwork { val module: PeripheryCounterModule val coreplex: CoreplexRISCVPlatform @@ -75,6 +109,8 @@ trait PeripheryCounterModule extends TopNetworkModule { } } +/// Coreplex will power-on running at 0x1000 (BootROM) + trait HardwiredResetVector extends TopNetwork { val module: HardwiredResetVectorModule val coreplex: CoreplexRISCVPlatform From e87f54d4f7ef575591ade02da42c80cb6fdce654 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 15:37:08 -0800 Subject: [PATCH 07/21] rocketchip: traits for adding external TL2 ports --- src/main/scala/rocketchip/Configs.scala | 5 +- src/main/scala/rocketchip/Periphery.scala | 84 ++++++++++++++++++++--- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 47c0937a..2a1aac3a 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -28,8 +28,9 @@ class BasePlatformConfig extends Config( case PeripheryBusArithmetic => true // Note that PLIC asserts that this is > 0. case IncludeJtagDTM => false - case ExtMem => AXIMasterConfig(0x80000000L, 0x10000000L, 8, 4) - case ExtBus => AXIMasterConfig(0x60000000L, 0x20000000L, 8, 4) + case ExtMem => MasterConfig(base=0x80000000L, size=0x10000000L, beatBytes=8, idBits=4) + case ExtBus => MasterConfig(base=0x60000000L, size=0x20000000L, beatBytes=8, idBits=4) + case ExtIn => SlaveConfig(beatBytes=8, idBits=8, sourceBits=2) case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock case _ => throw new CDEMatchError }) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 35d5306f..a654c8a0 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -20,9 +20,11 @@ import scala.math.max import coreplex._ /** Specifies the size of external memory */ -case class AXIMasterConfig(base: Long, size: Long, beatBytes: Int, idBits: Int) -case object ExtMem extends Field[AXIMasterConfig] -case object ExtBus extends Field[AXIMasterConfig] +case class MasterConfig(base: Long, size: Long, beatBytes: Int, idBits: Int) +case object ExtMem extends Field[MasterConfig] +case object ExtBus extends Field[MasterConfig] +case class SlaveConfig(beatBytes: Int, idBits: Int, sourceBits: Int) +case object ExtIn extends Field[SlaveConfig] /** Specifies the number of external interrupts */ case object NExtTopInterrupts extends Field[Int] /** Source of RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra **/ @@ -155,14 +157,17 @@ trait PeripheryMasterAXI4MMIOModule { // PeripherySlaveAXI4 is an example, make your own cake pattern like this one. trait PeripherySlaveAXI4 extends L2Crossbar { - private val axiIdBits = 8 - private val tlIdBits = 2 // at most 4 AXI requets inflight at a time - + private val config = p(ExtIn) val l2_axi4 = AXI4BlindInputNode(AXI4MasterPortParameters( masters = Seq(AXI4MasterParameters( - id = IdRange(0, 1 << axiIdBits))))) + id = IdRange(0, 1 << config.idBits))))) - l2.node := TLSourceShrinker(1 << tlIdBits)(AXI4ToTL()(AXI4Fragmenter()(l2_axi4))) + l2.node := + TLSourceShrinker(1 << config.sourceBits)( + TLWidthWidget(config.beatBytes)( + AXI4ToTL()( + AXI4Fragmenter()( + l2_axi4)))) } trait PeripherySlaveAXI4Bundle extends L2CrossbarBundle { @@ -178,6 +183,69 @@ trait PeripherySlaveAXI4Module extends L2CrossbarModule { ///// +// Add an external TL-UL slave +trait PeripheryMasterTLMMIO { + this: TopNetwork => + + private val config = p(ExtBus) + val mmio_tl = TLBlindOutputNode(TLManagerPortParameters( + managers = Seq(TLManagerParameters( + address = List(AddressSet(BigInt(config.base), config.size-1)), + executable = true, + supportsGet = TransferSizes(1, cacheBlockBytes), + supportsPutFull = TransferSizes(1, cacheBlockBytes), + supportsPutPartial = TransferSizes(1, cacheBlockBytes))), + beatBytes = config.beatBytes)) + + mmio_tl := + TLSourceShrinker(config.idBits)( + TLWidthWidget(socBusConfig.beatBytes)( + socBus.node)) +} + +trait PeripheryMasterTLMMIOBundle { + this: TopNetworkBundle { + val outer: PeripheryMasterTLMMIO + } => + val mmio_tl = outer.mmio_tl.bundleOut +} + +trait PeripheryMasterTLMMIOModule { + this: TopNetworkModule { + val outer: PeripheryMasterTLMMIO + val io: PeripheryMasterTLMMIOBundle + } => + // nothing to do +} + +///// + +// NOTE: this port is NOT allowed to issue Acquires +trait PeripherySlaveTL extends L2Crossbar { + private val config = p(ExtIn) + val l2_tl = TLBlindInputNode(TLClientPortParameters( + clients = Seq(TLClientParameters( + sourceId = IdRange(0, 1 << config.idBits))))) + + l2.node := + TLSourceShrinker(1 << config.sourceBits)( + TLWidthWidget(config.beatBytes)( + l2_tl)) +} + +trait PeripherySlaveTLBundle extends L2CrossbarBundle { + val outer: PeripherySlaveTL + val l2_tl = outer.l2_tl.bundleIn +} + +trait PeripherySlaveTLModule extends L2CrossbarModule { + val outer: PeripherySlaveTL + val io: PeripherySlaveTLBundle + // nothing to do +} + +///// + trait PeripheryBootROM { this: TopNetwork => val coreplex: CoreplexRISCVPlatform From 566cc9e60b06106fbad652222a1df08fec2fe657 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 16:04:54 -0800 Subject: [PATCH 08/21] rocketchip: RTCPeriod config --- src/main/scala/rocketchip/Configs.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 2a1aac3a..8ab15a9d 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -169,3 +169,9 @@ class WithNBreakpoints(hwbp: Int) extends Config ( case _ => throw new CDEMatchError } ) + +class WithRTCPeriod(nCycles: Int) extends Config( + (pname, site, here) => pname match { + case RTCPeriod => nCycles + case _ => throw new CDEMatchError + }) From 9f1c668c4fe349b91d308f440d8fc40e6d8f1ddc Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 18:06:33 -0800 Subject: [PATCH 09/21] config: when modifying Parameters, subordinate lookups use top --- src/main/scala/coreplex/Configs.scala | 30 ++++++++++++------------- src/main/scala/groundtest/Configs.scala | 4 ++-- src/main/scala/rocketchip/Configs.scala | 6 ++--- src/main/scala/util/Config.scala | 3 ++- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 01a34c53..71cd5434 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -124,39 +124,39 @@ class WithNCores(n: Int) extends Config( class WithNBanksPerMemChannel(n: Int) extends Config( (pname, site, here, up) => pname match { - case BankedL2Config => up(BankedL2Config).copy(nBanksPerChannel = n) + case BankedL2Config => up(BankedL2Config, site).copy(nBanksPerChannel = n) case _ => throw new CDEMatchError }) class WithNTrackersPerBank(n: Int) extends Config( (pname, site, here, up) => pname match { - case BroadcastConfig => up(BroadcastConfig).copy(nTrackers = n) + case BroadcastConfig => up(BroadcastConfig, site).copy(nTrackers = n) case _ => throw new CDEMatchError }) // This is the number of sets **per way** class WithL1ICacheSets(sets: Int) extends Config( (pname, site, here, up) => pname match { - case CacheName("L1I") => up(CacheName("L1I")).copy(nSets = sets) + case CacheName("L1I") => up(CacheName("L1I"), site).copy(nSets = sets) case _ => throw new CDEMatchError }) // This is the number of sets **per way** class WithL1DCacheSets(sets: Int) extends Config( (pname, site, here, up) => pname match { - case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = sets) + case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = sets) case _ => throw new CDEMatchError }) class WithL1ICacheWays(ways: Int) extends Config( (pname, site, here, up) => pname match { - case CacheName("L1I") => up(CacheName("L1I")).copy(nWays = ways) + case CacheName("L1I") => up(CacheName("L1I"), site).copy(nWays = ways) case _ => throw new CDEMatchError }) class WithL1DCacheWays(ways: Int) extends Config( (pname, site, here, up) => pname match { - case CacheName("L1D") => up(CacheName("L1D")).copy(nWays = ways) + case CacheName("L1D") => up(CacheName("L1D"), site).copy(nWays = ways) case _ => throw new CDEMatchError }) @@ -169,7 +169,7 @@ class WithCacheBlockBytes(linesize: Int) extends Config( class WithDataScratchpad(n: Int) extends Config( (pname,site,here,up) => pname match { case DataScratchpadSize => n - case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = n / site(CacheBlockBytes)) + case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = n / site(CacheBlockBytes)) case _ => throw new CDEMatchError }) @@ -188,7 +188,7 @@ class WithL2Cache extends Config( class WithBufferlessBroadcastHub extends Config( (pname, site, here, up) => pname match { - case BroadcastConfig => up(BroadcastConfig).copy(bufferless = true) + case BroadcastConfig => up(BroadcastConfig, site).copy(bufferless = true) }) /** @@ -206,12 +206,12 @@ class WithBufferlessBroadcastHub extends Config( class WithStatelessBridge extends Config( (pname,site,here,up) => pname match { /* !!! FIXME - case BankedL2Config => up(BankedL2Config).copy(coherenceManager = { case (_, _) => + case BankedL2Config => up(BankedL2Config, site).copy(coherenceManager = { case (_, _) => val pass = LazyModule(new TLBuffer(0)) (pass.node, pass.node) }) */ - case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) + case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0) case _ => throw new CDEMatchError }) @@ -227,7 +227,7 @@ class WithL2Capacity(size_kb: Int) extends Config( class WithNL2Ways(n: Int) extends Config( (pname,site,here,up) => pname match { - case CacheName("L2") => up(CacheName("L2")).copy(nWays = n) + case CacheName("L2") => up(CacheName("L2"), site).copy(nWays = n) }) class WithRV32 extends Config( @@ -239,7 +239,7 @@ class WithRV32 extends Config( class WithBlockingL1 extends Config( (pname,site,here,up) => pname match { - case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) + case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0) case _ => throw new CDEMatchError }) @@ -250,9 +250,9 @@ class WithSmallCores extends Config( case UseVM => false case BtbKey => BtbParameters(nEntries = 0) case NAcquireTransactors => 2 - case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = 64, nWays = 1, nTLBEntries = 4) - case CacheName("L1I") => up(CacheName("L1I")).copy(nSets = 64, nWays = 1, nTLBEntries = 4) - case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) + case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4) + case CacheName("L1I") => up(CacheName("L1I"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4) + case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0) case _ => throw new CDEMatchError }) diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 02dc603f..b1301079 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -123,7 +123,7 @@ class WithAtomics extends Config( class WithPrefetches extends Config( (pname, site, here, up) => pname match { - case ComparatorKey => up(ComparatorKey).copy(prefetches = true) + case ComparatorKey => up(ComparatorKey, site).copy(prefetches = true) case _ => throw new CDEMatchError }) @@ -202,6 +202,6 @@ class WithTraceGen extends Config( }.flatten } case UseAtomics => true - case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = 16, nWays = 1) + case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = 16, nWays = 1) case _ => throw new CDEMatchError }) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 8ab15a9d..b89e58e7 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -57,14 +57,14 @@ class PLRUL2Config extends Config(new WithPLRU ++ new DefaultL2Config) class WithNMemoryChannels(n: Int) extends Config( (pname,site,here,up) => pname match { - case BankedL2Config => up(BankedL2Config).copy(nMemoryChannels = n) + case BankedL2Config => up(BankedL2Config, site).copy(nMemoryChannels = n) case _ => throw new CDEMatchError } ) class WithExtMemSize(n: Long) extends Config( (pname,site,here,up) => pname match { - case ExtMem => up(ExtMem).copy(size = n) + case ExtMem => up(ExtMem, site).copy(size = n) case _ => throw new CDEMatchError } ) @@ -95,7 +95,7 @@ class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig) class WithEdgeDataBits(dataBits: Int) extends Config( (pname, site, here, up) => pname match { - case ExtMem => up(ExtMem).copy(beatBytes = dataBits/8) + case ExtMem => up(ExtMem, site).copy(beatBytes = dataBits/8) case _ => throw new CDEMatchError }) diff --git a/src/main/scala/util/Config.scala b/src/main/scala/util/Config.scala index 966b594b..fca8b747 100644 --- a/src/main/scala/util/Config.scala +++ b/src/main/scala/util/Config.scala @@ -6,7 +6,8 @@ class CDEMatchError() extends Exception { } abstract class View { - final def apply[T](pname: Field[T]): T = find(pname, this).asInstanceOf[T] + final def apply[T](pname: Field[T]): T = apply(pname, this) + final def apply[T](pname: Field[T], site: View): T = find(pname, site).asInstanceOf[T] protected[config] def find(pname: Any, site: View): Any } From 30e890b4803f4d328856a590cf716cf88b804661 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 18:53:03 -0800 Subject: [PATCH 10/21] diplomacy: include InternalNodes for AXI4 and TL --- src/main/scala/uncore/axi4/Nodes.scala | 3 +++ src/main/scala/uncore/tilelink2/Nodes.scala | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/scala/uncore/axi4/Nodes.scala b/src/main/scala/uncore/axi4/Nodes.scala index b8fb1efd..717b07da 100644 --- a/src/main/scala/uncore/axi4/Nodes.scala +++ b/src/main/scala/uncore/axi4/Nodes.scala @@ -53,3 +53,6 @@ case class AXI4InputNode() extends InputNode(AXI4Imp) // Nodes used for external ports case class AXI4BlindOutputNode(portParams: AXI4SlavePortParameters) extends BlindOutputNode(AXI4Imp)(portParams) case class AXI4BlindInputNode(portParams: AXI4MasterPortParameters) extends BlindInputNode(AXI4Imp)(portParams) + +case class AXI4InternalOutputNode(portParams: AXI4SlavePortParameters) extends InternalOutputNode(AXI4Imp)(portParams) +case class AXI4InternalInputNode(portParams: AXI4MasterPortParameters) extends InternalInputNode(AXI4Imp)(portParams) diff --git a/src/main/scala/uncore/tilelink2/Nodes.scala b/src/main/scala/uncore/tilelink2/Nodes.scala index 07cbd94c..dc06dc8a 100644 --- a/src/main/scala/uncore/tilelink2/Nodes.scala +++ b/src/main/scala/uncore/tilelink2/Nodes.scala @@ -126,6 +126,9 @@ case class TLInputNode() extends InputNode(TLImp) case class TLBlindOutputNode(portParams: TLManagerPortParameters) extends BlindOutputNode(TLImp)(portParams) case class TLBlindInputNode(portParams: TLClientPortParameters) extends BlindInputNode(TLImp)(portParams) +case class TLInternalOutputNode(portParams: TLManagerPortParameters) extends InternalOutputNode(TLImp)(portParams) +case class TLInternalInputNode(portParams: TLClientPortParameters) extends InternalInputNode(TLImp)(portParams) + /** Synthesizeable unit tests */ import unittest._ From a670f63c81b6630b8c1a84aeae4d395d7ed46f54 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 18:53:22 -0800 Subject: [PATCH 11/21] periphery: a handy trait to turn-off ExtMem --- src/main/scala/rocketchip/Periphery.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index a654c8a0..af859346 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -72,6 +72,14 @@ trait PeripheryExtInterruptsModule { ///// +trait PeripheryNoMem extends TopNetwork { + private val channels = p(BankedL2Config).nMemoryChannels + require (channels == 0) + val mem = Seq() +} + +///// + trait PeripheryMasterAXI4Mem { this: TopNetwork => val module: PeripheryMasterAXI4MemModule From 6aeadc4551d73ba4519e8b971d4a9d7bc089b08e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 23 Nov 2016 20:53:36 -0800 Subject: [PATCH 12/21] regression: disable ComparatorL2Config for now This tests atomics against the L2. However, we don't have an L2 yet so this is hitting the broadcast hub, which does not support these operations. --- regression/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression/Makefile b/regression/Makefile index 45187027..4ecd8fe2 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -61,7 +61,7 @@ endif ifeq ($(SUITE),GroundtestSuiteB) PROJECT=groundtest CONFIGS=BroadcastRegressionTestConfig BufferlessRegressionTestConfig CacheRegressionTestConfig \ - ComparatorConfig ComparatorBufferlessConfig ComparatorL2Config ComparatorStatelessConfig + ComparatorConfig ComparatorBufferlessConfig ComparatorStatelessConfig endif ifeq ($(SUITE),UnittestSuite) From 0baa1c9a45eb10fcfa789a9ff99d1fbbb2e29b11 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 24 Nov 2016 15:50:49 -0800 Subject: [PATCH 13/21] coreplex: CacheBlockOffsetBits was wrong! This bug is ancient. I don't understand how it never mattered before. Anyway, in processors with a custom CacheBlockBytes, this value is wrong! The symptom is that TL1 components end up missing high address bits. This causes, for example, a system to jump to 0 instead of RAM. I don't understand how this very serious bug did not cause problems before. --- src/main/scala/coreplex/Configs.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 71cd5434..ff6e8946 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -109,7 +109,7 @@ class BaseCoreplexConfig extends Config ( case BroadcastConfig => BroadcastConfig() case BankedL2Config => BankedL2Config() case CacheBlockBytes => 64 - case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) + case CacheBlockOffsetBits => log2Up(site(CacheBlockBytes)) case EnableL2Logging => false case _ => throw new CDEMatchError } From f19d504c88af3c0eeb8e916e49896c6b02ed5e9b Mon Sep 17 00:00:00 2001 From: Colin Schmidt Date: Fri, 25 Nov 2016 01:50:01 -0800 Subject: [PATCH 14/21] Use % in makefrag-verilog to prevent double firrtl execution (#452) * Use % in makefrag-verilog to prevent double firrtl execution --- vsim/Makefrag-verilog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vsim/Makefrag-verilog b/vsim/Makefrag-verilog index 953bff80..cedceada 100644 --- a/vsim/Makefrag-verilog +++ b/vsim/Makefrag-verilog @@ -12,9 +12,9 @@ $(generated_dir)/%.fir $(generated_dir)/%.prm $(generated_dir)/%.d: $(FIRRTL_JAR mkdir -p $(dir $@) cd $(base_dir) && $(SBT) "run-main $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)" -$(generated_dir)/$(long_name).v $(generated_dir)/$(long_name).conf : $(firrtl) $(FIRRTL_JAR) +$(generated_dir)/%.v $(generated_dir)/%.conf: $(generated_dir)/%.fir $(FIRRTL_JAR) mkdir -p $(dir $@) - $(FIRRTL) -i $< -o $(generated_dir)/$(long_name).v -X verilog --infer-rw $(MODEL) --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$(long_name).conf + $(FIRRTL) -i $< -o $(generated_dir)/$*.v -X verilog --infer-rw $(MODEL) --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$*.conf $(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf $(mem_gen) cd $(generated_dir) && \ From 1e0aca7358057127f6fa4029d8203a10bbac3bc6 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 25 Nov 2016 15:26:22 -0800 Subject: [PATCH 15/21] dcache: the high bit of s2_req.typ is the SIGN bit (not size) (#455) --- src/main/scala/rocket/Dcache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/Dcache.scala b/src/main/scala/rocket/Dcache.scala index 8b999b0d..635191df 100644 --- a/src/main/scala/rocket/Dcache.scala +++ b/src/main/scala/rocket/Dcache.scala @@ -251,7 +251,7 @@ class DCacheModule(outer: DCache)(implicit p: Parameters) extends HellaCacheModu val a_source = PriorityEncoder(~uncachedInFlight.asUInt) val acquire_address = s2_req_block_addr val access_address = s2_req.addr - val a_size = s2_req.typ + val a_size = s2_req.typ(MT_SZ-2, 0) val a_data = Fill(beatWords, pstore1_storegen.data) val acquire = if (edge.manager.anySupportAcquire) { edge.Acquire(a_source, acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb From 2b80386a9e6aa965acbe2fadbb3e129390972cec Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 25 Nov 2016 17:02:29 -0800 Subject: [PATCH 16/21] rocketchip: TileInterrupts needs a TLCacheEdge (#456) --- src/main/scala/coreplex/RocketTiles.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/RocketTiles.scala b/src/main/scala/coreplex/RocketTiles.scala index 78a1097a..def17d2a 100644 --- a/src/main/scala/coreplex/RocketTiles.scala +++ b/src/main/scala/coreplex/RocketTiles.scala @@ -57,7 +57,7 @@ class AsyncRocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule { val uncached = uncachedOut.bundleOut val slave = slaveNode.map(_.bundleIn) val hartid = UInt(INPUT, p(XLen)) - val interrupts = new TileInterrupts().asInput + val interrupts = new TileInterrupts()(rocket.coreParams).asInput val resetVector = UInt(INPUT, p(XLen)) } rocket.module.io.interrupts := ShiftRegister(io.interrupts, 3) From d755edffcc634215319a0c63ffeb03ae16a6e9be Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 25 Nov 2016 18:10:28 -0800 Subject: [PATCH 17/21] DebugTransport: use ToAsyncDebugBus for correct depth --- .../scala/rocketchip/DebugTransport.scala | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/main/scala/rocketchip/DebugTransport.scala b/src/main/scala/rocketchip/DebugTransport.scala index 1d4949a3..596d6c52 100644 --- a/src/main/scala/rocketchip/DebugTransport.scala +++ b/src/main/scala/rocketchip/DebugTransport.scala @@ -38,32 +38,25 @@ case object IncludeJtagDTM extends Field[Boolean] * */ -class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) - extends Module { - +class JtagDTMWithSync(implicit val p: Parameters) extends Module { // io.DebugBusIO <-> Sync <-> DebugBusIO <-> UInt <-> DTM Black Box val io = new Bundle { - val jtag = new JTAGIO(true).flip val debug = new AsyncDebugBusIO - } val req_width = io.debug.req.mem(0).getWidth val resp_width = io.debug.resp.mem(0).getWidth - val jtag_dtm = Module (new DebugTransportModuleJtag(req_width, resp_width)) - + val jtag_dtm = Module(new DebugTransportModuleJtag(req_width, resp_width)) jtag_dtm.io.jtag <> io.jtag - val dtm_req = Wire(new DecoupledIO(UInt(width = req_width))) - val dtm_resp = Wire(new DecoupledIO(UInt(width = resp_width))) - val io_debug_bus = Wire (new DebugBusIO) + io.debug <> ToAsyncDebugBus(io_debug_bus) - io.debug.req <> ToAsyncBundle(io_debug_bus.req) - io_debug_bus.resp <> FromAsyncBundle(io.debug.resp) + val dtm_req = jtag_dtm.io.dtm_req + val dtm_resp = jtag_dtm.io.dtm_resp // Translate from straight 'bits' interface of the blackboxes // into the Resp/Req data structures. @@ -74,20 +67,12 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) dtm_resp.valid := io_debug_bus.resp.valid dtm_resp.bits := io_debug_bus.resp.bits.asUInt io_debug_bus.resp.ready := dtm_resp.ready - - dtm_req <> jtag_dtm.io.dtm_req - jtag_dtm.io.dtm_resp <> dtm_resp } class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters) extends BlackBox { - val io = new Bundle { val jtag = new JTAGIO(true).flip() - val dtm_req = new DecoupledIO(UInt(width = reqSize)) - val dtm_resp = new DecoupledIO(UInt(width = respSize)).flip() - } - } From 233280e7d2b25c7d287d8904ca7fa48033d246ee Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 25 Nov 2016 18:11:01 -0800 Subject: [PATCH 18/21] AsyncBundle: save a wasted bit when depth=1 --- src/main/scala/util/AsyncBundle.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/util/AsyncBundle.scala b/src/main/scala/util/AsyncBundle.scala index fb178666..81057779 100644 --- a/src/main/scala/util/AsyncBundle.scala +++ b/src/main/scala/util/AsyncBundle.scala @@ -9,8 +9,8 @@ final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle { require (isPow2(depth)) val mem = Vec(depth, gen) - val ridx = UInt(width = log2Up(depth)+1).flip - val widx = UInt(width = log2Up(depth)+1) + val ridx = UInt(width = log2Ceil(depth)+1).flip + val widx = UInt(width = log2Ceil(depth)+1) val ridx_valid = Bool().flip val widx_valid = Bool() val source_reset_n = Bool() From a17753983a8b92b258d5cde9e32c2ba102fbe981 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 25 Nov 2016 19:38:24 -0800 Subject: [PATCH 19/21] coreplex: allow legacy devices to override the config string (#458) --- src/main/scala/coreplex/RISCVPlatform.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala index 804854d4..374ef4ee 100644 --- a/src/main/scala/coreplex/RISCVPlatform.scala +++ b/src/main/scala/coreplex/RISCVPlatform.scala @@ -29,7 +29,9 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork { lazy val configString = { val managers = l1tol2.node.edgesIn(0).manager.managers - rocketchip.GenerateConfigString(p, clint, plic, managers) + // Use the existing config string if the user overrode it + ConfigStringOutput.contents.getOrElse( + rocketchip.GenerateConfigString(p, clint, plic, managers)) } } From 4e3682f8890cc338d84747d5e1da09c62323da11 Mon Sep 17 00:00:00 2001 From: Richard Xia Date: Sat, 26 Nov 2016 12:24:10 -0800 Subject: [PATCH 20/21] Bump chisel3 by just one commit to pull in gitignore for firrtl.jar. --- chisel3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chisel3 b/chisel3 index 224ee397..0a8c369f 160000 --- a/chisel3 +++ b/chisel3 @@ -1 +1 @@ -Subproject commit 224ee397db324067b35874bf22c76a63e9ca531b +Subproject commit 0a8c369f388bac326bfe8a598aaf6d8fa13e6dfa From 4146f6a792277297bd80d4b6f1b6f2b3cb0f31d7 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 26 Nov 2016 15:11:42 -0800 Subject: [PATCH 21/21] TLB: do not access illegal addresses (#460) --- src/main/scala/rocket/tlb.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/rocket/tlb.scala b/src/main/scala/rocket/tlb.scala index 12da4628..7f1659dc 100644 --- a/src/main/scala/rocket/tlb.scala +++ b/src/main/scala/rocket/tlb.scala @@ -65,8 +65,10 @@ class TLB(implicit val p: Parameters) extends Module with HasTLBParameters { val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0) val do_refill = Bool(usingVM) && io.ptw.resp.valid val mpu_ppn = Mux(do_refill, refill_ppn, passthrough_ppn) + val mpu_physaddr = mpu_ppn << pgIdxBits + val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_) def fastCheck(member: TLManagerParameters => Boolean) = - Mux1H(edge.manager.findFast(mpu_ppn << pgIdxBits), edge.manager.managers.map(m => Bool(member(m)))) + legal_address && Mux1H(edge.manager.findFast(mpu_physaddr), edge.manager.managers.map(m => Bool(member(m)))) val prot_r = fastCheck(_.supportsGet) val prot_w = fastCheck(_.supportsPutFull) val prot_x = fastCheck(_.executable)