1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
4 import byucc.edif.tools.merge.*;
8 import edu.berkeley.slipway.*;
9 import edu.berkeley.abits.*;
10 import com.atmel.fpslic.*;
11 import static com.atmel.fpslic.FpslicConstants.*;
12 import static edu.berkeley.slipway.mpar.PhysicalDevice.*;
13 import static edu.berkeley.slipway.mpar.NetList.*;
16 // FIXME: make sure everything is O(design), not O(device)
17 public class Routing {
19 public final Placement placement;
20 public final NetList netlist;
21 public final PhysicalDevice pd;
23 private HashSet<Route> removed = new HashSet<Route>();
24 private HashSet<Route> added = new HashSet<Route>();
25 public void checkpoint() {
29 public void rollback() {
30 for (Route r : added) r.remove(false);
31 for (Route r : removed) r.add();
34 public Routing(Placement p) {
36 this.netlist = p.netlist;
38 congestion = new double[pd.getNumPhysicalNets()];
39 load = new int[pd.getNumPhysicalNets()];
42 private double[] congestion;
44 public HashMap<NetList.LogicalNet, Route> routes =
45 new HashMap<NetList.LogicalNet, Route>();
48 private NetList.LogicalNet logicalNet;
49 private HashSet<PhysicalDevice.PhysicalNet> nets;
50 private HashSet<PhysicalDevice.PhysicalPip> pips;
52 public Route(NetList.LogicalNet logicalNet,
53 HashSet<PhysicalDevice.PhysicalNet> nets,
54 HashSet<PhysicalDevice.PhysicalPip> pips
56 this.logicalNet = logicalNet;
61 for(PhysicalDevice.PhysicalNet net : nets)
64 routes.put(logicalNet, this);
66 public void remove() { remove(true); }
67 public void remove(boolean note) {
68 for(PhysicalDevice.PhysicalNet net : nets)
70 if (note) removed.add(this);
71 routes.remove(logicalNet);
75 public void setPips(boolean on) {
76 for (Route r : routes.values())
77 for (PhysicalDevice.PhysicalPip pip : r.pips)
81 public int getLoad(PhysicalDevice.PhysicalNet pn) { return load[pn.idx]; }
82 public double getCongestion(PhysicalDevice.PhysicalNet pn) { return congestion[pn.idx]; }
84 public void routeAll() throws RoutingFailedException {
85 for(NetList.LogicalNet net : netlist.nets)
88 public void reRouteAll() throws RoutingFailedException {
89 for(NetList.LogicalNet net : netlist.nets) {
94 public void unRouteAll() {
95 for(NetList.LogicalNet signal : netlist.getLogicalNets())
100 public void unroute(NetList.Node node) {
101 if (node==null) return;
102 for(NetList.Node.Port p : node)
106 public void unroute(PhysicalDevice.PhysicalNet net) {
107 while(netToSignals.size(net) > 0)
108 unroute(netToSignals.getAll(net).iterator().next());
111 public void unroute(NetList.LogicalNet signal) {
112 if (signal==null) return;
113 Route r = routes.get(signal);
114 if (r != null) r.remove();
117 public void unrouteOverloaded() {
120 for(PhysicalDevice.PhysicalNet pn : pd)
126 public void updateCongestion(double alphaParameter, double betaParameter) {
127 for(PhysicalDevice.PhysicalNet net : pd) {
128 double c = getCongestion(net);
129 c = c * alphaParameter;
130 if (getLoad(net) > 1) c += betaParameter;
131 congestion[net.idx] = c;
135 public static class RoutingFailedException extends Exception { }
137 public static int iteration = 1;
139 private HashSet<PhysicalDevice.PhysicalNet> remainingDests = new HashSet<PhysicalDevice.PhysicalNet>();
140 private PriorityQueue<PhysicalDevice.PhysicalNet> pq = new PriorityQueue<PhysicalDevice.PhysicalNet>();
141 public void route(NetList.LogicalNet logicalNet) throws RoutingFailedException {
142 double maxDelay = 10;
143 boolean tryHard = true;
145 if (logicalNet.driver == null) return;
146 if (logicalNet.getSize() <= 1) return;
147 if (isRouted(logicalNet)) return;
150 for(NetList.Node.Port p : logicalNet.ports)
151 if (p != logicalNet.driver) {
152 PhysicalDevice.PhysicalNet dest;
154 case 0: dest = placement.nodeToCell(p.getNode()).getNet("xi"); break;
155 case 1: dest = placement.nodeToCell(p.getNode()).getNet("yi"); break;
156 default: throw new Error();
158 dest.remaining = true;
163 PhysicalDevice.PhysicalNet source = placement.nodeToCell(logicalNet.driver.getNode()).getNet("out");
165 source.distance = -1 * maxDelay;
167 source.iteration = iteration;
170 HashSet<PhysicalDevice.PhysicalNet> nets = new HashSet<PhysicalDevice.PhysicalNet>();
171 HashSet<PhysicalDevice.PhysicalPip> pips = new HashSet<PhysicalDevice.PhysicalPip>();
173 PhysicalDevice.PhysicalNet pn = pq.poll();
174 if (pn==null) throw new RoutingFailedException();
175 double frontier = pn.distance;
176 for(PhysicalDevice.PhysicalPip pip : pn) {
177 for(PhysicalDevice.PhysicalNet net : pip.getDrivenNets()) {
178 if (net.iteration != iteration) {
179 net.iteration = iteration;
180 net.distance = Double.MAX_VALUE;
182 double newfrontier = frontier + pip.getCost(pn, net);
183 newfrontier += getCongestion(net);
184 if (getLoad(net) > 0) newfrontier += 1000;
186 // penalty for using any net already routed in this iteration (makes routing order-sensitive)
187 //if (net.load >= 1) newfrontier = newfrontier + 20;
189 if (net.distance <= newfrontier) continue;
190 net.distance = newfrontier;
192 net.backpointer = pn;
193 net.depth = pn.depth+1;
195 if (!net.remaining) continue;
197 net.remaining = false;
198 // Vaughn Betz style multiterminal routing: once we reach one sink, make every node on the path
199 // "distance zero" from the source.
201 if (newfrontier > 0) ts += newfrontier;
202 for(PhysicalDevice.PhysicalNet p = net; p != source; p = p.backpointer) {
203 PhysicalDevice.PhysicalPip pipx = p.getPipFrom(p.backpointer); // FIXME: this call is actually slow
205 if (pipx.driver != null) nets.add(pipx.driver);
206 for(PhysicalDevice.PhysicalNet n : pipx.driven) nets.add(n);
207 p.distance = source.distance;
211 if (remaining==0) break OUTER;
215 Route r = new Route(logicalNet, nets, pips);
217 r.timingpenalty = ts;
221 public boolean isRouted(NetList.LogicalNet n) { return routes.get(n) != null; }
222 //public boolean isRouted(PhysicalDevice.PhysicalNet pn) { return netToSignal.get(pn) != null; }
223 //public PhysicalDevice.PhysicalNet signalToNet(NetList.LogicalNet n) { return signalToNets.get(n); }
224 //public NetList.LogicalNet netToSignal(PhysicalDevice.PhysicalNet pn) { return netToSignals.get(pn); }
226 public double measureCongestion() {
227 double congestion = 0;
228 for(PhysicalDevice.PhysicalNet pn : pd)
230 congestion += getLoad(pn)-1;
231 for(NetList.LogicalNet ln : netlist.nets)
233 congestion = Double.MAX_VALUE;
237 public double measureWireCost() {
239 for(PhysicalDevice.PhysicalNet pn : pd)
244 public double measureTimingpenalty() {
246 for(Route r : routes.values())
247 ret += r.timingpenalty;
251 public int measureOverloaded() {
253 for(PhysicalDevice.PhysicalNet pn : pd)
259 public double measureWireUtilization() {
262 for(PhysicalDevice.PhysicalNet pn : pd) {
266 return ((double)used)/((double)numwires);
269 public void draw(Graphics2D g) {
270 for(NetList.LogicalNet signal : netlist.nets)
273 public void draw(Graphics2D g, NetList.LogicalNet signal) {
274 g.setColor(/*getLoad(pip1.driver) >= 2 ? Color.red :*/ Color.blue);
275 for(Route r : routes.values()) {
276 for(PhysicalDevice.PhysicalNet net : r.nets) {
277 for(PhysicalDevice.PhysicalPip pip1 : net) {
278 if (!r.pips.contains(pip1)) continue;
279 for(PhysicalDevice.PhysicalPip pip2 : net) {
280 if (!r.pips.contains(pip2)) continue;
282 g.drawLine(pip1.getX(),