📄 routing.java
字号:
} // do the unrouting for(int j=0; j<total; j++) { if (unrouteNet(netsToUnroute[j], arcsToDelete.get(j), nodesToDelete.get(j), netEnds.get(j), netList, highlightThese)) break; } fieldVariableChanged("highlightThese"); return true; } public void terminateOK() { UserInterface ui = Job.getUserInterface(); EditWindow_ wnd = ui.getCurrentEditWindow_(); if (wnd == null) return; wnd.clearHighlighting(); for(ArcInst ai : highlightThese) wnd.addElectricObject(ai, ai.getParent()); wnd.finishedHighlighting(); } private static boolean unrouteNet(Network net, Set<ArcInst> arcsToDelete, Set<NodeInst> nodesToDelete, List<Connection> netEnds, Netlist netList, List<ArcInst> highlightThese) { // remove marked nodes and arcs for(ArcInst ai : arcsToDelete) { ai.kill(); } Cell cell = net.getParent(); cell.killNodes(nodesToDelete); // now create the new unrouted wires double wid = Generic.tech().unrouted_arc.getDefaultLambdaBaseWidth(); int count = netEnds.size(); int [] covered = new int[count]; Point2D [] points = new Point2D[count]; for(int i=0; i<count; i++) { Connection con = netEnds.get(i); PortInst pi = con.getPortInst(); Poly poly = pi.getPoly(); points[i] = new Point2D.Double(poly.getCenterX(), poly.getCenterY()); covered[i] = 0; } for(int first=0; ; first++) { boolean found = true; double bestdist = 0; int besti = 0, bestj = 0; for(int i=0; i<count; i++) { for(int j=i+1; j<count; j++) { if (first != 0) { if (covered[i] + covered[j] != 1) continue; } double dist = points[i].distance(points[j]); if (!found && dist >= bestdist) continue; found = false; bestdist = dist; besti = i; bestj = j; } } if (found) break; covered[besti] = covered[bestj] = 1; PortInst head = netEnds.get(besti).getPortInst(); PortInst tail = netEnds.get(bestj).getPortInst(); ArcInst ai = ArcInst.makeInstanceBase(Generic.tech().unrouted_arc, wid, head, tail); if (ai == null) { System.out.println("Could not create unrouted arc"); return true; } highlightThese.add(ai); } return false; } } /** * Method to find the endpoints of a network. * @param net the network to "unroute". * @param arcsToDelete a HashSet of arcs that should be deleted. * @param nodesToDelete a HashSet of nodes that should be deleted. * @param netList the netlist for the current cell. * @param mustBeUnrouted true to include all items on the network in the list of arcs/nodes to delete. * False to only include items from the generic technology or pins with no exports. * @return a List of Connection (PortInst/Point2D pairs) that should be wired together. */ public static List<Connection> findNetEnds(Network net, Set<ArcInst> arcsToDelete, Set<NodeInst> nodesToDelete, Netlist netList, boolean mustBeUnrouted) { // initialize Cell cell = net.getParent(); List<Connection> endList = new ArrayList<Connection>(); // look at every arc and see if it is part of the network for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); if (mustBeUnrouted && ai.getProto() != Generic.tech().unrouted_arc) continue; Network aNet = netList.getNetwork(ai, 0); if (aNet != net) continue; arcsToDelete.add(ai); // see if an end of the arc is a network "end" for(int i=0; i<2; i++) { Connection thisCon = ai.getConnection(i); PortInst pi = thisCon.getPortInst(); NodeInst ni = pi.getNodeInst(); // see if this arc end is a "termination point" (on cell, exported, or not further connected) boolean term = true; if (!ni.hasExports() && !ni.isCellInstance()) { // see if this primitive connects to other unconnected nets for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst conAi = con.getArc(); if (mustBeUnrouted && conAi.getProto() != Generic.tech().unrouted_arc) continue; if (conAi != ai && netList.getNetwork(conAi, 0) == net) { term = false; break; } } } // if a termination point, consider it for the list of net ends if (term) { // see if it is already in the list, connection-wise boolean found = false; Netlist nl = null; for(Connection lCon : endList) { PortInst otherPI = lCon.getPortInst(); NodeInst otherNI = otherPI.getNodeInst(); if (otherNI != ni) continue; if (otherPI == pi) { found = true; break; } // connecting to another port on a node: ignore if they are connected internally if (ni.isCellInstance()) { if (nl == null) nl = ((Cell)ni.getProto()).acquireUserNetlist(); if (nl == null) continue; Network subNet = nl.getNetwork((Export)pi.getPortProto(), 0); Network otherSubNet = nl.getNetwork((Export)otherPI.getPortProto(), 0); if (subNet == otherSubNet) { found = true; break; } } else { PrimitivePort subPP = (PrimitivePort)pi.getPortProto(); PrimitivePort otherSubPP = (PrimitivePort)otherPI.getPortProto(); if (subPP.getTopology() == otherSubPP.getTopology()) { found = true; break; } } } if (!found) endList.add(thisCon); } else { // not a network end: mark the node for removal boolean deleteNode = !mustBeUnrouted; if (ni.getProto().getFunction() == PrimitiveNode.Function.PIN) deleteNode = true; if (deleteNode) nodesToDelete.add(ni); } } } return endList; } /** * Method to return the most recent routing activity. */ public Activity getLastActivity() { return past; } /****************************** SUN ROUTER INTERFACE ******************************/ private static boolean sunRouterChecked = false; private static Class<?> sunRouterClass = null; private static Method sunRouterMethod; /** * Method to tell whether the Sun Router is available. * This is a proprietary tool from Sun Microsystems. * This method dynamically figures out whether the router is present by using reflection. * @return true if the Sun Router is available. */ public static boolean hasSunRouter() { if (!sunRouterChecked) { sunRouterChecked = true; // find the Sun Router class try { sunRouterClass = Class.forName("com.sun.electric.plugins.sunRouter.SunRouter"); } catch (ClassNotFoundException e) { sunRouterClass = null; return false; } // find the necessary method on the router class try { sunRouterMethod = sunRouterClass.getMethod("routeCell", new Class[] {Cell.class}); } catch (NoSuchMethodException e) { sunRouterClass = null; return false; } } // if already initialized, return if (sunRouterClass == null) return false; return true; } /** * Method to invoke the Sun Router via reflection. */ public static void sunRouteCurrentCell() { if (!hasSunRouter()) return; UserInterface ui = Job.getUserInterface(); Cell curCell = ui.needCurrentCell(); if (curCell == null) return; try { sunRouterMethod.invoke(sunRouterClass, new Object[] {curCell}); } catch (Exception e) { System.out.println("Unable to run the Sun Router module"); e.printStackTrace(System.out); } } /****************************** COPY / PASTE ROUTING TOPOLOGY ******************************/ private static Cell copiedTopologyCell; /** * Method called when the "Copy Routing Topology" command is issued. * It remembers the topology in the current cell. */ public static void copyRoutingTopology() { UserInterface ui = Job.getUserInterface(); Cell np = ui.needCurrentCell(); if (np == null) return; copiedTopologyCell = np; System.out.println("Cell " + np.describe(true) + " will have its connectivity remembered"); } /** * Method called when the "Paste Routing Topology" command is issued. * It applies the topology of the "copied" cell to the current cell. */ public static void pasteRoutingTopology() { if (copiedTopologyCell == null) { System.out.println("Must copy topology before pasting it"); return; } // first validate the source cell if (!copiedTopologyCell.isLinked()) { System.out.println("Copied cell is no longer valid"); return; } // get the destination cell UserInterface ui = Job.getUserInterface(); Cell toCell = ui.needCurrentCell(); if (toCell == null) return; // make sure copy goes to a different cell if (copiedTopologyCell == toCell) { System.out.println("Topology must be copied to a different cell"); return; } // do the copy new CopyRoutingTopology(copiedTopologyCell, toCell); } /** * Class to delete a cell in a new thread. */ private static class CopyRoutingTopology extends Job { private Cell fromCell, toCell; protected CopyRoutingTopology(Cell fromCell, Cell toCell) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -