package com.sun.electric.tool.generator.flag.router; import java.util.Collection; import java.util.TreeSet; import com.sun.electric.tool.generator.flag.Utils; import com.sun.electric.tool.Job; /** All the channels for one layer */ public class LayerChannels { private TreeSet<Channel> channels = new TreeSet<Channel>(); private static void prln(String msg) {Utils.prln(msg);} private boolean isHorizontal() { Job.error(channels.size()==0, "can't tell direction because no channels"); return channels.first().isHorizontal(); } public LayerChannels() { } public void add(Channel ch) { if (ch.hasTracks()) channels.add(ch); } public Collection<Channel> getChannels() {return channels;} /** For a horizontal layer, find a channel that covers a vertical pin * at x from y1 to y2. */ public Channel findChanOverVertInterval(double x, double y1, double y2) { double yMin = Math.min(y1, y2); double yMax = Math.max(y1, y2); if (channels.size()==0) return null; Job.error(!isHorizontal(), "not sure what this means yet"); for (Channel c : channels) { Job.error(x<c.getMinTrackEnd() || x > c.getMaxTrackEnd(), "channels can't cover X"); if (c.getMaxTrackCenter()<yMin) continue; if (c.getMinTrackCenter()>yMax) break;; return c; } return null; } /** For a vertical layer, find a vertical channel between x1 and x2 * that can connect the two horizontal channels: horChan1 and horChan2. */ public Channel findVertBridge(Channel horChan1, Channel horChan2, double x1, double x2) { if (channels.size()==0) return null; Job.error(isHorizontal(), "layer must be vertical"); double yMin = Math.min(horChan1.getMinTrackCenter(), horChan2.getMinTrackCenter()); double yMax = Math.max(horChan1.getMaxTrackCenter(), horChan2.getMaxTrackCenter()); double xMin = Math.min(x1, x2); double xMax = Math.max(x1, x2); double maxOverlap = -Double.MAX_VALUE; Channel bestChan = null; for (Channel c : channels) { if (yMax>c.getMaxTrackEnd() || yMin<c.getMinTrackEnd()) { prln("channels can't cover Y"); } // calculate how much of the vertical channel overlaps with // [x1, x2]. If channel doesn't overlap with [x1, x2] then // measure the distance between the channel and [x1, x2] double startX = Math.max(xMin, c.getMinTrackCenter()); double endX = Math.min(xMax, c.getMaxTrackCenter()); double overlap = endX - startX; if (overlap>maxOverlap) { maxOverlap = overlap; bestChan = c; } // ideally I should check to see if channel has enough // capacity } return bestChan; } public String toString() { StringBuffer sb = new StringBuffer(); // sb.append(isHorizontal() ? " Horizontal " : " Vertical "); // sb.append("channel\n"); for (Channel c : channels) sb.append(c.toString()); return sb.toString(); } public int numChannels() {return channels.size();} }