diplomacy: optimize IdRange.contains (#798)
This should make an optimal circuit for a wider class of ranges.
This commit is contained in:
parent
d316aeb275
commit
93d423d202
@ -33,10 +33,20 @@ case class IdRange(start: Int, end: Int) extends Ordered[IdRange]
|
|||||||
|
|
||||||
def contains(x: Int) = start <= x && x < end
|
def contains(x: Int) = start <= x && x < end
|
||||||
def contains(x: UInt) =
|
def contains(x: UInt) =
|
||||||
if (start+1 == end) { UInt(start) === x }
|
if (size == 1) { // simple comparison
|
||||||
else if (isPow2(end-start) && ((end | start) & (end-start-1)) == 0)
|
x === UInt(start)
|
||||||
{ ~(~(UInt(start) ^ x) | UInt(end-start-1)) === UInt(0) }
|
} else {
|
||||||
else { UInt(start) <= x && x < UInt(end) }
|
// find index of largest different bit
|
||||||
|
val largestDeltaBit = log2Floor(start ^ (end-1))
|
||||||
|
val smallestCommonBit = largestDeltaBit + 1 // may not exist in x
|
||||||
|
val uncommonMask = (1 << smallestCommonBit) - 1
|
||||||
|
val uncommonBits = (x | UInt(0, width=smallestCommonBit))(largestDeltaBit, 0)
|
||||||
|
// the prefix must match exactly (note: may shift ALL bits away)
|
||||||
|
(x >> smallestCommonBit) === UInt(start >> smallestCommonBit) &&
|
||||||
|
// firrtl constant prop range analysis can eliminate these two:
|
||||||
|
UInt(start & uncommonMask) <= uncommonBits &&
|
||||||
|
uncommonBits <= UInt((end-1) & uncommonMask)
|
||||||
|
}
|
||||||
|
|
||||||
def shift(x: Int) = IdRange(start+x, end+x)
|
def shift(x: Int) = IdRange(start+x, end+x)
|
||||||
def size = end - start
|
def size = end - start
|
||||||
|
Loading…
Reference in New Issue
Block a user