From ba3c83287f9e6e6c4270df892287896ab20276e9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 3 Nov 2016 19:05:53 -0700 Subject: [PATCH] tilelink2 Xbar: merge the AddressSets of fractured managers --- src/main/scala/diplomacy/Parameters.scala | 21 +++++++++- .../scala/uncore/tilelink2/Parameters.scala | 42 +++++++++++++++++++ src/main/scala/uncore/tilelink2/Xbar.scala | 4 +- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index e494f6e7..a262966a 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -144,5 +144,24 @@ object AddressSet misaligned(base+step, size-step, AddressSet(base, step-1) +: tail) } } -} + def unify(seq: Seq[AddressSet]): Seq[AddressSet] = { + val n = seq.size + val array = Array(seq:_*) + var filter = Array.fill(n) { false } + for (i <- 0 until n-1) { if (!filter(i)) { + for (j <- i+1 until n) { if (!filter(j)) { + val a = array(i) + val b = array(j) + if (a.mask == b.mask && isPow2(a.base ^ b.base)) { + val c_base = a.base & ~(a.base ^ b.base) + val c_mask = a.mask | (a.base ^ b.base) + filter.update(j, true) + array.update(i, AddressSet(c_base, c_mask)) + } + }} + }} + val out = (array zip filter) flatMap { case (a, f) => if (f) None else Some(a) } + if (out.size != n) unify(out) else out.toList + } +} diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 0a0da860..f732efd9 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -287,3 +287,45 @@ case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: T { val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base)) } + +object ManagerUnification +{ + def apply(managers: Seq[TLManagerParameters]) = { + // To be unified, devices must agree on all of these terms + case class TLManagerKey( + regionType: RegionType.T, + executable: Boolean, + lastNode: BaseNode, + supportsAcquire: TransferSizes, + supportsArithmetic: TransferSizes, + supportsLogical: TransferSizes, + supportsGet: TransferSizes, + supportsPutFull: TransferSizes, + supportsPutPartial: TransferSizes, + supportsHint: TransferSizes) + def key(x: TLManagerParameters) = TLManagerKey( + regionType = x.regionType, + executable = x.executable, + lastNode = x.nodePath.last, + supportsAcquire = x.supportsAcquire, + supportsArithmetic = x.supportsArithmetic, + supportsLogical = x.supportsLogical, + supportsGet = x.supportsGet, + supportsPutFull = x.supportsPutFull, + supportsPutPartial = x.supportsPutPartial, + supportsHint = x.supportsHint) + val map = scala.collection.mutable.HashMap[TLManagerKey, TLManagerParameters]() + managers.foreach { m => + val k = key(m) + map.get(k) match { + case None => map.update(k, m) + case Some(n) => { + map.update(k, m.copy( + address = m.address ++ n.address, + fifoId = None)) // Merging means it's not FIFO anymore! + } + } + } + map.values.map(m => m.copy(address = AddressSet.unify(m.address))).toList + } +} diff --git a/src/main/scala/uncore/tilelink2/Xbar.scala b/src/main/scala/uncore/tilelink2/Xbar.scala index f4c6a82b..6e2b64a0 100644 --- a/src/main/scala/uncore/tilelink2/Xbar.scala +++ b/src/main/scala/uncore/tilelink2/Xbar.scala @@ -54,13 +54,13 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst) extends Lazy seq(0).copy( minLatency = seq.map(_.minLatency).min, endSinkId = outputIdRanges.map(_.end).max, - managers = (outputIdRanges zip seq) flatMap { case (range, port) => + managers = ManagerUnification(seq.flatMap { port => require (port.beatBytes == seq(0).beatBytes) val fifoIdMapper = fifoIdFactory() port.managers map { manager => manager.copy( fifoId = manager.fifoId.map(fifoIdMapper(_)) )} - } + }) ) })