diplomacy: support given bits in AddressDecoder
This commit is contained in:
parent
c0b6d31377
commit
d4b3a0f0be
@ -19,7 +19,7 @@ object AddressDecoder
|
|||||||
// Find the minimum subset of bits needed to disambiguate port addresses.
|
// Find the minimum subset of bits needed to disambiguate port addresses.
|
||||||
// ie: inspecting only the bits in the output, you can look at an address
|
// ie: inspecting only the bits in the output, you can look at an address
|
||||||
// and decide to which port (outer Seq) the address belongs.
|
// and decide to which port (outer Seq) the address belongs.
|
||||||
def apply(ports: Ports): BigInt = if (ports.size <= 1) 0 else {
|
def apply(ports: Ports, givenBits: BigInt = BigInt(0)): BigInt = if (ports.size <= 1) givenBits else {
|
||||||
// Every port must have at least one address!
|
// Every port must have at least one address!
|
||||||
ports.foreach { p => require (!p.isEmpty) }
|
ports.foreach { p => require (!p.isEmpty) }
|
||||||
// Verify the user did not give us an impossible problem
|
// Verify the user did not give us an impossible problem
|
||||||
@ -30,9 +30,11 @@ object AddressDecoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
val maxBits = log2Ceil(ports.map(_.map(_.max).max).max + 1)
|
val maxBits = log2Ceil(ports.map(_.map(_.max).max).max + 1)
|
||||||
val bits = (0 until maxBits).map(BigInt(1) << _).toSeq
|
val (bitsToTry, bitsToTake) = (0 until maxBits).map(BigInt(1) << _).partition(b => (givenBits & b) == 0)
|
||||||
val selected = recurse(Seq(ports.map(_.sorted).sorted(portOrder)), bits)
|
val partitions = Seq(ports.map(_.sorted).sorted(portOrder))
|
||||||
val output = selected.reduceLeft(_ | _)
|
val givenPartitions = bitsToTake.foldLeft(partitions) { (p, b) => partitionPartitions(p, b) }
|
||||||
|
val selected = recurse(givenPartitions, bitsToTry.toSeq)
|
||||||
|
val output = selected.reduceLeft(_ | _) | givenBits
|
||||||
|
|
||||||
// Modify the AddressSets to allow the new wider match functions
|
// Modify the AddressSets to allow the new wider match functions
|
||||||
val widePorts = ports.map { _.map { _.widen(~output) } }
|
val widePorts = ports.map { _.map { _.widen(~output) } }
|
||||||
@ -103,6 +105,7 @@ object AddressDecoder
|
|||||||
// requirement: ports have sorted addresses and are sorted lexicographically
|
// requirement: ports have sorted addresses and are sorted lexicographically
|
||||||
val debug = false
|
val debug = false
|
||||||
def recurse(partitions: Partitions, bits: Seq[BigInt]): Seq[BigInt] = {
|
def recurse(partitions: Partitions, bits: Seq[BigInt]): Seq[BigInt] = {
|
||||||
|
if (partitions.map(_.size <= 1).reduce(_ && _)) Seq() else {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
println("Partitioning:")
|
println("Partitioning:")
|
||||||
partitions.foreach { partition =>
|
partitions.foreach { partition =>
|
||||||
@ -121,10 +124,6 @@ object AddressDecoder
|
|||||||
}
|
}
|
||||||
val (bestScore, bestBit, bestPartitions) = candidates.min(Ordering.by[(Seq[Int], BigInt, Partitions), Iterable[Int]](_._1.toIterable))
|
val (bestScore, bestBit, bestPartitions) = candidates.min(Ordering.by[(Seq[Int], BigInt, Partitions), Iterable[Int]](_._1.toIterable))
|
||||||
if (debug) println("=> Selected bit 0x%x".format(bestBit))
|
if (debug) println("=> Selected bit 0x%x".format(bestBit))
|
||||||
if (bestScore(0) <= 1) {
|
|
||||||
if (debug) println("---")
|
|
||||||
Seq(bestBit)
|
|
||||||
} else {
|
|
||||||
bestBit +: recurse(bestPartitions, bits.filter(_ != bestBit))
|
bestBit +: recurse(bestPartitions, bits.filter(_ != bestBit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user