X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fslipway%2Fmpar%2FPhysicalDevice.java;fp=src%2Fedu%2Fberkeley%2Fslipway%2Fmpar%2FPhysicalDevice.java;h=8d8b9ed40f9efa0bdaa0d6f05f28ed0430489cba;hb=ab5e85e23cfb5d3d73a8d1c16588f81efd59f006;hp=0000000000000000000000000000000000000000;hpb=23c3a27c11b7023032c50d9dcb4eb58314c2ae22;p=slipway.git diff --git a/src/edu/berkeley/slipway/mpar/PhysicalDevice.java b/src/edu/berkeley/slipway/mpar/PhysicalDevice.java new file mode 100644 index 0000000..8d8b9ed --- /dev/null +++ b/src/edu/berkeley/slipway/mpar/PhysicalDevice.java @@ -0,0 +1,320 @@ +package edu.berkeley.slipway.mpar; +import com.atmel.fpslic.*; +import byucc.edif.tools.merge.*; +import byucc.edif.*; +import java.io.*; +import java.util.*; +import edu.berkeley.slipway.*; +import com.atmel.fpslic.*; +import static com.atmel.fpslic.FpslicConstants.*; +import static edu.berkeley.slipway.mpar.MPARDemo.*; + +public class PhysicalDevice { + private final Fpslic fpslic; + + public final int width; + public final int height; + private final PhysicalNet[][][][] sectorWires; + private final PhysicalCell[][] cells; + + public PhysicalCell getCell(int col, int row) { + if (col<0) return null; + if (row<0) return null; + if (col>=width) return null; + if (row>=height) return null; + return cells[col][row]; + } + + public PhysicalDevice(final Fpslic fpslic, int width, int height) { + this.fpslic = fpslic; + this.width = width; + this.height = height; + sectorWires = new PhysicalNet[width][height][5][2]; + for(int x=0; x remainingDests = new HashSet(); + for(PhysicalNet dest : dests) remainingDests.add(dest); + + HashSet needsReset = new HashSet(); + PriorityQueue pq = new PriorityQueue(); + needsReset.add(source); + source.distance = 0; + pq.add(source); + + OUTER: while(true) { + PhysicalNet pn = pq.poll(); + if (pn==null) throw new Error("unroutable! " + source + " -> " + dests[0]); + double frontier = pn.distance; + for(PhysicalPip pip : pn) + for(PhysicalNet net : pip.getDrivenNets()) { + double newfrontier = frontier + 0.05 + net.congestion; + + // penalty for using any net already routed in this iteration (makes routing order-sensitive) + if (net.load >= 1) newfrontier = newfrontier + 20; + + if (net.distance <= newfrontier) continue; + pq.remove(net); // if already in there + net.distance = newfrontier; + pq.add(net); + needsReset.add(net); + net.backpointer = pn; + if (remainingDests.contains(net)) { + remainingDests.remove(net); + if (remainingDests.size()==0) break OUTER; + + // Vaughn Betz style multiterminal routing: once we reach one sink, make every node on the path + // "distance zero" from the source. + for(PhysicalNet pnx = net; pnx != null; pnx = pnx.backpointer) { + //pnx.distance = 0; + pq.add(pnx); + } + break; + } + } + } + + for(PhysicalNet dest : dests) { + PhysicalNet pn = dest; + while(pn != null && pn.backpointer != null) { + pn.owners.add(owner); + owner.pns.add(pn); + if (pn.distance != Double.MAX_VALUE) { + pn.distance = Double.MAX_VALUE; + pn.load++; + if (pn.load>=2) pn.congestion += betaParameter; + } + PhysicalPip pip = pn.getPipFrom(pn.backpointer); + pip.set(true); + owner.pips.add(pip); + pn = pn.backpointer; + } + // FIXME: check pn==source at this point + } + + for(PhysicalNet pn : needsReset) { + pn.distance = Double.MAX_VALUE; + pn.backpointer = null; + } + } + public HashSet allPhysicalNets = new HashSet(); + public class PhysicalNet implements Iterable, Comparable { + public double congestion = 0; + public int load = 0; + public double distance = Double.MAX_VALUE; + public PhysicalNet backpointer = null; + + public int compareTo(PhysicalNet pn) { + double x = distance - pn.distance; + return distance > pn.distance + ? 1 + : distance < pn.distance + ? -1 + : 0; + } + + private final HashSet pips = new HashSet(); + public Iterator iterator() { return pips.iterator(); } + private String name; + public PhysicalNet(String name) { + this.name = name; + allPhysicalNets.add(this); + } + public String toString() { return name; } + private void addPip(PhysicalPip pip) { pips.add(pip); } + public PhysicalPip getPipFrom(PhysicalNet pn) { + for(PhysicalPip pip : pn) + for(PhysicalNet pn2 : pip.getDrivenNets()) + if (pn2==this) + return pip; + return null; + } + public HashSet owners = new HashSet(); + } + + public abstract class PhysicalPip { + private PhysicalNet driver; + private PhysicalNet[] driven; + private String name; + private int defaultCost; + public String toString() { return name; } + public PhysicalNet getDriverNet() { return driver; } + public PhysicalNet[] getDrivenNets() { return driven; } + public int getCost(PhysicalNet in, PhysicalNet out) { return defaultCost; } + public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven) { this(name, driver, driven, 100); } + public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven, int defaultCost) { + this.name = name; + this.driver = driver; + this.driven = driven; + this.defaultCost = defaultCost; + if (driver != null) driver.addPip(this); + for(PhysicalNet pn : driven) pn.addPip(this); + } + public abstract void set(boolean connected); + } + +}