From 7aba066e6755c844d478a00b54c6f05d07ed05a2 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 16:20:27 -0800 Subject: [PATCH 1/6] tilelink2: add TLZero; /dev/zero suitable for putting behind locked cache ways --- src/main/scala/uncore/tilelink2/Zero.scala | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/scala/uncore/tilelink2/Zero.scala diff --git a/src/main/scala/uncore/tilelink2/Zero.scala b/src/main/scala/uncore/tilelink2/Zero.scala new file mode 100644 index 00000000..2da7f940 --- /dev/null +++ b/src/main/scala/uncore/tilelink2/Zero.scala @@ -0,0 +1,44 @@ +// See LICENSE.SiFive for license details. + +package uncore.tilelink2 + +import Chisel._ +import config._ +import diplomacy._ + +class TLZero(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule +{ + val node = TLManagerNode(Seq(TLManagerPortParameters( + Seq(TLManagerParameters( + address = List(address), + regionType = RegionType.UNCACHED, + executable = executable, + supportsGet = TransferSizes(1, beatBytes), + supportsPutPartial = TransferSizes(1, beatBytes), + supportsPutFull = TransferSizes(1, beatBytes), + fifoId = Some(0))), // requests are handled in order + beatBytes = beatBytes, + minLatency = 1))) // no bypass needed for this device + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = node.bundleIn + } + + val in = io.in(0) + val edge = node.edgesIn(0) + + val a = Queue(in.a, 2) + val hasData = edge.hasData(a.bits) + + a.ready := in.d.ready + in.d.valid := a.valid + in.d.bits := edge.AccessAck(a.bits, UInt(0)) + in.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData) + + // Tie off unused channels + in.b.valid := Bool(false) + in.c.ready := Bool(true) + in.e.ready := Bool(true) + } +} From 7afe383db3fa4ff76719c78517560211e61fd18c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 16:21:09 -0800 Subject: [PATCH 2/6] Ecc: detect uncorrectable errors also for SEC --- src/main/scala/uncore/util/Ecc.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/uncore/util/Ecc.scala b/src/main/scala/uncore/util/Ecc.scala index b478e3c2..bfaaed12 100644 --- a/src/main/scala/uncore/util/Ecc.scala +++ b/src/main/scala/uncore/util/Ecc.scala @@ -10,7 +10,7 @@ abstract class Decoding def uncorrected: UInt def corrected: UInt def correctable: Bool - def uncorrectable: Bool + def uncorrectable: Bool // If true, correctable should be ignored def error = correctable || uncorrectable } @@ -81,7 +81,7 @@ class SECCode extends Code def uncorrected = swizzle(y) def corrected = swizzle(((y << 1) ^ UIntToOH(syndrome)) >> 1) def correctable = syndrome.orR - def uncorrectable = Bool(false) + def uncorrectable = syndrome > UInt(n) } private def mapping(i: Int) = i-1-log2Up(i) } From fc9ea62d38ac49813975e494cf5a376a08011b2e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 16:21:33 -0800 Subject: [PATCH 3/6] HeterogeneousBag: a handy container for differently parameterized bundles --- src/main/scala/util/HeterogeneousBag.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/scala/util/HeterogeneousBag.scala diff --git a/src/main/scala/util/HeterogeneousBag.scala b/src/main/scala/util/HeterogeneousBag.scala new file mode 100644 index 00000000..1aaff08d --- /dev/null +++ b/src/main/scala/util/HeterogeneousBag.scala @@ -0,0 +1,13 @@ +package util + +import Chisel._ +import chisel3.core.Record +import scala.collection.immutable.ListMap + +final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with collection.IndexedSeq[T] { + def apply(x: Int) = elts(x) + def length = elts.length + + val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, n) }:_*) + override def cloneType: this.type = (new HeterogeneousBag(elts.map(_.cloneType))).asInstanceOf[this.type] +} From b240505a1526eea51811fc985aa369a580333b7a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 16:55:44 -0800 Subject: [PATCH 4/6] rocketchip: move memory channel Xbar from coreplex to rocketchip We want to keep the banks split in the outer SoC if there is an L3. Furthermore, each channel might go to different memory subsystems, like DDR/HMC/Zero, from rocketchip. --- src/main/scala/coreplex/CoreplexNetwork.scala | 21 +++++++------- src/main/scala/groundtest/Top.scala | 2 +- src/main/scala/rocketchip/BaseTop.scala | 1 + src/main/scala/rocketchip/Periphery.scala | 28 ++++++++----------- .../scala/rocketchip/RocketPlexMaster.scala | 5 ++-- 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/main/scala/coreplex/CoreplexNetwork.scala b/src/main/scala/coreplex/CoreplexNetwork.scala index 9402548b..8d12ee95 100644 --- a/src/main/scala/coreplex/CoreplexNetwork.scala +++ b/src/main/scala/coreplex/CoreplexNetwork.scala @@ -71,27 +71,26 @@ trait CoreplexNetworkModule extends HasCoreplexParameters { trait BankedL2CoherenceManagers extends CoreplexNetwork { val module: BankedL2CoherenceManagersModule + require (isPow2(l2Config.nMemoryChannels)) require (isPow2(l2Config.nBanksPerChannel)) require (isPow2(l1tol2_lineBytes)) - val mem = TLOutputNode() - for (channel <- 0 until l2Config.nMemoryChannels) { - val bankBar = LazyModule(new TLXbar) - val (in, out) = l2Config.coherenceManager(p, this) - - in :*= l1tol2.node - mem := bankBar.node - - val mask = ~BigInt((l2Config.nBanksPerChannel-1) * l1tol2_lineBytes) + private val (in, out) = l2Config.coherenceManager(p, this) + private val mask = ~BigInt((l2Config.nBanks-1) * l1tol2_lineBytes) + val mem = Seq.tabulate(l2Config.nMemoryChannels) { channel => + val node = TLOutputNode() for (bank <- 0 until l2Config.nBanksPerChannel) { - bankBar.node := TLFilter(AddressSet(bank * l1tol2_lineBytes, mask))(out) + val offset = (bank * l2Config.nMemoryChannels) + channel + in := l1tol2.node + node := TLFilter(AddressSet(offset * l1tol2_lineBytes, mask))(out) } + node } } trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle { val outer: BankedL2CoherenceManagers - val mem = outer.mem.bundleOut + val mem = HeterogeneousBag(outer.mem.map(_.bundleOut)) } trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule { diff --git a/src/main/scala/groundtest/Top.scala b/src/main/scala/groundtest/Top.scala index 5e328089..9fb40686 100644 --- a/src/main/scala/groundtest/Top.scala +++ b/src/main/scala/groundtest/Top.scala @@ -17,7 +17,7 @@ class GroundTestTop(implicit p: Parameters) extends BaseTop socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode - mem.foreach { _ := coreplex.mem } + (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } } class GroundTestTopBundle[+L <: GroundTestTop](_outer: L) extends BaseTopBundle(_outer) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 0a9bdec7..b5a8c582 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -35,6 +35,7 @@ trait TopNetwork extends HasPeripheryParameters { val peripheryBus = LazyModule(new TLXbar) val intBus = LazyModule(new IntXbar) val l2 = LazyModule(new TLBuffer) + val mem = Seq.fill(p(coreplex.BankedL2Config).nMemoryChannels) { LazyModule(new TLXbar) } peripheryBus.node := TLBuffer()( diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 5e544754..1d05843f 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -72,28 +72,21 @@ 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 private val config = p(ExtMem) private val channels = p(BankedL2Config).nMemoryChannels + private val lineBytes = p(CacheBlockBytes) - val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(channels) { i => - val c_size = config.size/channels - val c_base = config.base + c_size*i + val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(channels) { channel => + val base = AddressSet(config.base, config.size-1) + val filter = AddressSet(channel * lineBytes, ~((channels-1) * lineBytes)) AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( - address = List(AddressSet(c_base, c_size-1)), + address = base.intersect(filter).toList, regionType = RegionType.UNCACHED, // cacheable executable = true, supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers @@ -102,10 +95,13 @@ trait PeripheryMasterAXI4Mem { beatBytes = config.beatBytes) }) - val mem = Seq.fill(channels) { - val converter = LazyModule(new TLToAXI4(config.idBits)) - mem_axi4 := AXI4Buffer()(converter.node) - converter.node + private val converter = LazyModule(new TLToAXI4(config.idBits)) + private val buffer = LazyModule(new AXI4Buffer) + + mem foreach { case xbar => + converter.node := xbar.node + buffer.node := converter.node + mem_axi4 := buffer.node } } diff --git a/src/main/scala/rocketchip/RocketPlexMaster.scala b/src/main/scala/rocketchip/RocketPlexMaster.scala index 0f7d1c05..06591dbb 100644 --- a/src/main/scala/rocketchip/RocketPlexMaster.scala +++ b/src/main/scala/rocketchip/RocketPlexMaster.scala @@ -12,14 +12,15 @@ import coreplex._ trait RocketPlexMaster extends TopNetwork { val module: RocketPlexMasterModule - val mem: Seq[TLInwardNode] val coreplex = LazyModule(new DefaultCoreplex) coreplex.l2in :=* l2.node socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode - mem.foreach { _ := coreplex.mem } + + require (mem.size == coreplex.mem.size) + (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } } trait RocketPlexMasterBundle extends TopNetworkBundle { From a3e56cfa5ed958a191f36a0d8bc2309af94cc11f Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 17:18:20 -0800 Subject: [PATCH 5/6] rocketchip: add Zero device to the memory subsystem --- src/main/scala/rocketchip/Configs.scala | 2 ++ src/main/scala/rocketchip/ExampleTop.scala | 3 ++ src/main/scala/rocketchip/Periphery.scala | 33 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index a2d9c24b..7ee8ba1e 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -31,6 +31,7 @@ class BasePlatformConfig extends Config((site, here, up) => { case PeripheryBusArithmetic => true // Note that PLIC asserts that this is > 0. case IncludeJtagDTM => false + case ZeroConfig => ZeroConfig(base=0xa000000L, size=0x2000000L, beatBytes=8) 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) @@ -86,6 +87,7 @@ class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig) class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => { case ExtMem => up(ExtMem, site).copy(beatBytes = dataBits/8) + case ZeroConfig => up(ZeroConfig, site).copy(beatBytes = dataBits/8) }) class Edge128BitConfig extends Config( diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 1c466ca7..66fd1112 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -30,6 +30,7 @@ class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](_outer: L, _ class ExampleRocketTop(implicit p: Parameters) extends ExampleTop with PeripheryBootROM + with PeripheryZero with PeripheryDebug with PeripheryCounter with HardwiredResetVector @@ -39,6 +40,7 @@ class ExampleRocketTop(implicit p: Parameters) extends ExampleTop class ExampleRocketTopBundle[+L <: ExampleRocketTop](_outer: L) extends ExampleTopBundle(_outer) with PeripheryBootROMBundle + with PeripheryZeroBundle with PeripheryDebugBundle with PeripheryCounterBundle with HardwiredResetVectorBundle @@ -46,6 +48,7 @@ class ExampleRocketTopBundle[+L <: ExampleRocketTop](_outer: L) extends ExampleT class ExampleRocketTopModule[+L <: ExampleRocketTop, +B <: ExampleRocketTopBundle[L]](_outer: L, _io: () => B) extends ExampleTopModule(_outer, _io) with PeripheryBootROMModule + with PeripheryZeroModule with PeripheryDebugModule with PeripheryCounterModule with HardwiredResetVectorModule diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 1d05843f..53b201e4 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -34,6 +34,9 @@ case object PeripheryBusConfig extends Field[TLBusConfig] case object PeripheryBusArithmetic extends Field[Boolean] /* Specifies the SOC-bus configuration */ case object SOCBusConfig extends Field[TLBusConfig] +/* Specifies the location of the Zero device */ +case class ZeroConfig(base: Long, size: Long, beatBytes: Int) +case object ZeroConfig extends Field[ZeroConfig] /** Utility trait for quick access to some relevant parameters */ trait HasPeripheryParameters { @@ -121,6 +124,36 @@ trait PeripheryMasterAXI4MemModule { ///// +trait PeripheryZero { + this: TopNetwork => + val module: PeripheryZeroModule + + private val config = p(ZeroConfig) + private val address = AddressSet(config.base, config.size-1) + private val lineBytes = p(CacheBlockBytes) + + val zeros = mem map { case xbar => + val zero = LazyModule(new TLZero(address, beatBytes = config.beatBytes)) + zero.node := TLFragmenter(config.beatBytes, lineBytes)(xbar.node) + zero + } +} + +trait PeripheryZeroBundle { + this: TopNetworkBundle { + val outer: PeripheryZero + } => +} + +trait PeripheryZeroModule { + this: TopNetworkModule { + val outer: PeripheryZero + val io: PeripheryZeroBundle + } => +} + +///// + // PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one. trait PeripheryMasterAXI4MMIO { this: TopNetwork => From d1744a566780ebd89f573d180343a9a638f24889 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 3 Feb 2017 19:00:08 -0800 Subject: [PATCH 6/6] coreplex: zero memory channels is also allowed --- src/main/scala/coreplex/CoreplexNetwork.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/CoreplexNetwork.scala b/src/main/scala/coreplex/CoreplexNetwork.scala index 8d12ee95..d4b700aa 100644 --- a/src/main/scala/coreplex/CoreplexNetwork.scala +++ b/src/main/scala/coreplex/CoreplexNetwork.scala @@ -71,7 +71,7 @@ trait CoreplexNetworkModule extends HasCoreplexParameters { trait BankedL2CoherenceManagers extends CoreplexNetwork { val module: BankedL2CoherenceManagersModule - require (isPow2(l2Config.nMemoryChannels)) + require (isPow2(l2Config.nMemoryChannels) || l2Config.nMemoryChannels == 0) require (isPow2(l2Config.nBanksPerChannel)) require (isPow2(l1tol2_lineBytes))