From 2210e71f429f92887e5913b4fba9474fc25a6318 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 16 Sep 2016 00:49:05 -0700 Subject: [PATCH] tilelink2 AddressDecoder: validate output of optimization --- .../scala/uncore/tilelink2/AddressDecoder.scala | 15 +++++++++++++-- src/main/scala/uncore/tilelink2/Parameters.scala | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/AddressDecoder.scala b/src/main/scala/uncore/tilelink2/AddressDecoder.scala index adddc8a5..ea7cacac 100644 --- a/src/main/scala/uncore/tilelink2/AddressDecoder.scala +++ b/src/main/scala/uncore/tilelink2/AddressDecoder.scala @@ -28,11 +28,22 @@ object AddressDecoder require (!a.overlaps(b)) // it must be possible to disambiguate ports! } } } + val maxBits = log2Ceil(ports.map(_.map(_.max).max).max + 1) val bits = (0 until maxBits).map(BigInt(1) << _).toSeq val selected = recurse(Seq(ports.map(_.sorted).sorted(portOrder)), bits) - selected.reduceLeft(_ | _) - // port validation via mask expansion + val output = selected.reduceLeft(_ | _) + + // Modify the AddressSets to allow the new wider match functions + val widePorts = ports.map { _.map { _.widen(~output) } } + // Verify that it remains possible to disambiguate all ports + widePorts.combinations(2).foreach { case Seq(x, y) => + x.foreach { a => y.foreach { b => + require (!a.overlaps(b)) + } } + } + + output } // A simpler version that works for a Seq[Int] diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 6423db3c..7c49e792 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -98,6 +98,9 @@ case class AddressSet(base: BigInt, mask: BigInt) extends Ordered[AddressSet] // A strided slave serves discontiguous ranges def strided = alignment1 != mask + // Widen the match function to ignore all bits in imask + def widen(imask: BigInt) = AddressSet(base & ~imask, mask | imask) + // AddressSets have one natural Ordering (the containment order) def compare(x: AddressSet) = { val primary = (this.base - x.base).signum // smallest address first