diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index 795f98a9..4e8ef4c1 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -17,14 +17,16 @@ object RegionType { } // A non-empty half-open range; [start, end) -case class IdRange(start: Int, end: Int) +case class IdRange(start: Int, end: Int) extends Ordered[IdRange] { require (start >= 0, s"Ids cannot be negative, but got: $start.") require (start < end, "Id ranges cannot be empty.") - // This is a strict partial ordering - def <(x: IdRange) = end <= x.start - def >(x: IdRange) = x < this + def compare(x: IdRange) = { + val primary = (this.start - x.start).signum + val secondary = (x.end - this.end).signum + if (primary != 0) primary else secondary + } def overlaps(x: IdRange) = start < x.end && x.start < end def contains(x: IdRange) = start <= x.start && x.end <= end @@ -43,6 +45,14 @@ case class IdRange(start: Int, end: Int) def range = start until end } +object IdRange +{ + def overlaps(s: Seq[IdRange]) = if (s.isEmpty) None else { + val ranges = s.sorted + (ranges.tail zip ranges.init) find { case (a, b) => a overlaps b } + } +} + // An potentially empty inclusive range of 2-powers [min, max] (in bytes) case class TransferSizes(min: Int, max: Int) { diff --git a/src/main/scala/uncore/axi4/Parameters.scala b/src/main/scala/uncore/axi4/Parameters.scala index 9ef05c77..8642613e 100644 --- a/src/main/scala/uncore/axi4/Parameters.scala +++ b/src/main/scala/uncore/axi4/Parameters.scala @@ -79,7 +79,9 @@ case class AXI4MasterPortParameters( require (userBits >= 0) // Require disjoint ranges for ids - masters.combinations(2).foreach { case Seq(x,y) => require (!x.id.overlaps(y.id), s"$x and $y overlap") } + IdRange.overlaps(masters.map(_.id)).foreach { case (x, y) => + require (!x.overlaps(y), s"AXI4MasterParameters.id $x and $y overlap") + } } case class AXI4BundleParameters( diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 3665b15a..aec47951 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -199,9 +199,9 @@ case class TLClientPortParameters( require (minLatency >= 0) // Require disjoint ranges for Ids - clients.combinations(2).foreach({ case Seq(x,y) => - require (!x.sourceId.overlaps(y.sourceId)) - }) + IdRange.overlaps(clients.map(_.sourceId)).foreach { case (x, y) => + require (!x.overlaps(y), s"TLClientParameters.sourceId ${x} overlaps ${y}") + } // Bounds on required sizes def endSourceId = clients.map(_.sourceId.end).max