diplomacy: optimize IdRange overlap detection
This commit is contained in:
parent
30f1f1e7c7
commit
40f18e6e43
@ -17,14 +17,16 @@ object RegionType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A non-empty half-open range; [start, end)
|
// 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 >= 0, s"Ids cannot be negative, but got: $start.")
|
||||||
require (start < end, "Id ranges cannot be empty.")
|
require (start < end, "Id ranges cannot be empty.")
|
||||||
|
|
||||||
// This is a strict partial ordering
|
def compare(x: IdRange) = {
|
||||||
def <(x: IdRange) = end <= x.start
|
val primary = (this.start - x.start).signum
|
||||||
def >(x: IdRange) = x < this
|
val secondary = (x.end - this.end).signum
|
||||||
|
if (primary != 0) primary else secondary
|
||||||
|
}
|
||||||
|
|
||||||
def overlaps(x: IdRange) = start < x.end && x.start < end
|
def overlaps(x: IdRange) = start < x.end && x.start < end
|
||||||
def contains(x: IdRange) = start <= x.start && x.end <= 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
|
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)
|
// An potentially empty inclusive range of 2-powers [min, max] (in bytes)
|
||||||
case class TransferSizes(min: Int, max: Int)
|
case class TransferSizes(min: Int, max: Int)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,9 @@ case class AXI4MasterPortParameters(
|
|||||||
require (userBits >= 0)
|
require (userBits >= 0)
|
||||||
|
|
||||||
// Require disjoint ranges for ids
|
// 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(
|
case class AXI4BundleParameters(
|
||||||
|
@ -199,9 +199,9 @@ case class TLClientPortParameters(
|
|||||||
require (minLatency >= 0)
|
require (minLatency >= 0)
|
||||||
|
|
||||||
// Require disjoint ranges for Ids
|
// Require disjoint ranges for Ids
|
||||||
clients.combinations(2).foreach({ case Seq(x,y) =>
|
IdRange.overlaps(clients.map(_.sourceId)).foreach { case (x, y) =>
|
||||||
require (!x.sourceId.overlaps(y.sourceId))
|
require (!x.overlaps(y), s"TLClientParameters.sourceId ${x} overlaps ${y}")
|
||||||
})
|
}
|
||||||
|
|
||||||
// Bounds on required sizes
|
// Bounds on required sizes
|
||||||
def endSourceId = clients.map(_.sourceId.end).max
|
def endSourceId = clients.map(_.sourceId.end).max
|
||||||
|
Loading…
Reference in New Issue
Block a user