From 55326c29bb34befca17c2192cbbaa3ffa7798daa Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 3 Nov 2016 19:05:22 -0700 Subject: [PATCH] tilelink2: Filter adapter removes some of the address space --- src/main/scala/diplomacy/Parameters.scala | 11 +++++ src/main/scala/uncore/tilelink2/Filter.scala | 49 +++++++++++++++++++ .../scala/uncore/tilelink2/Parameters.scala | 2 + 3 files changed, 62 insertions(+) create mode 100644 src/main/scala/uncore/tilelink2/Filter.scala diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index ddbe96d9..e494f6e7 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -104,6 +104,17 @@ case class AddressSet(base: BigInt, mask: BigInt) extends Ordered[AddressSet] // Widen the match function to ignore all bits in imask def widen(imask: BigInt) = AddressSet(base & ~imask, mask | imask) + // Return an AddressSet that only contains the addresses both sets contain + def intersect(x: AddressSet): Option[AddressSet] = { + if (!overlaps(x)) { + None + } else { + val r_mask = mask & x.mask + val r_base = base | x.base + Some(AddressSet(r_base, r_mask)) + } + } + // AddressSets have one natural Ordering (the containment order, if contiguous) def compare(x: AddressSet) = { val primary = (this.base - x.base).signum // smallest address first diff --git a/src/main/scala/uncore/tilelink2/Filter.scala b/src/main/scala/uncore/tilelink2/Filter.scala new file mode 100644 index 00000000..c851f3f1 --- /dev/null +++ b/src/main/scala/uncore/tilelink2/Filter.scala @@ -0,0 +1,49 @@ +// See LICENSE for license details. + +package uncore.tilelink2 + +import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo +import diplomacy._ +import scala.math.{min,max} + +class TLFilter(select: AddressSet) extends LazyModule +{ + val node = TLAdapterNode( + clientFn = { case Seq(cp) => cp }, + managerFn = { case Seq(mp) => + mp.copy(managers = mp.managers.map { m => + val filtered = m.address.map(_.intersect(select)).flatten + val cap = TransferSizes(1, select.alignment.toInt) + if (filtered.isEmpty) { None } else { + Some(m.copy( + address = filtered, + supportsAcquire = m.supportsAcquire .intersect(cap), + supportsArithmetic = m.supportsArithmetic.intersect(cap), + supportsLogical = m.supportsLogical .intersect(cap), + supportsGet = m.supportsGet .intersect(cap), + supportsPutFull = m.supportsPutFull .intersect(cap), + supportsPutPartial = m.supportsPutPartial.intersect(cap), + supportsHint = m.supportsHint .intersect(cap))) + } + }.flatten) + }) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = node.bundleIn + val out = node.bundleOut + } + io.out <> io.in + } +} + +object TLFilter +{ + // applied to the TL source node; y.node := TLBuffer(x.node) + def apply(select: AddressSet)(x: TLOutwardNode)(implicit sourceInfo: SourceInfo): TLOutwardNode = { + val filter = LazyModule(new TLFilter(select)) + filter.node := x + filter.node + } +} diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 8ffea166..0a0da860 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -23,7 +23,9 @@ case class TLManagerParameters( fifoId: Option[Int] = None, customDTS: Option[String]= None) { + require (!address.isEmpty) address.foreach { a => require (a.finite) } + address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) } require (supportsPutFull.contains(supportsPutPartial))