📄 routing.java
字号:
super("Copy Routing Topology", Routing.tool, Job.Type.CHANGE, null, null, Job.Priority.USER); this.fromCell = fromCell; this.toCell = toCell; startJob(); } public boolean doIt() throws JobException { return copyTopology(fromCell, toCell); } } private static class NodeMatch { NodeInst ni; String name; NodeInst otherNi; NodeMatch(NodeInst ni, String name) { this.ni = ni; this.name = name; } void findEquivalentByName(Cell other) { // match by name String thisName = ni.getName(); for(Iterator<NodeInst> it = other.getNodes(); it.hasNext(); ) { NodeInst oNi = it.next(); if (oNi.getName().equals(thisName)) { otherNi = oNi; return; } } // match by export if (!ni.isCellInstance() && ni.hasExports()) { for(Iterator<Export> it = ni.getExports(); it.hasNext(); ) { Export e = it.next(); String eName = e.getName(); for(Iterator<Export> oIt = other.getExports(); oIt.hasNext(); ) { Export oE = oIt.next(); if (eName.equalsIgnoreCase(oE.getName())) { otherNi = oE.getOriginalPort().getNodeInst(); return; } } } } } } /** * Method to copy the routing topology from one cell to another. * @param fromCell the source of the routing topology. * @param toCell the destination cell for the routing topology. * @return true if successful. */ public static boolean copyTopology(Cell fromCell, Cell toCell) { // make a list of all networks System.out.println("Copying topology of " + fromCell + " to " + toCell); Netlist nl = fromCell.acquireUserNetlist(); // first make a list of all nodes in the "from" cell Map<NodeInst,List<NodeMatch>> nodeMap = new HashMap<NodeInst,List<NodeMatch>>(); List<NodeMatch> unmatched = new ArrayList<NodeMatch>(); for(Iterator<NodeInst> it = fromCell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode || ni.getProto() == Generic.tech().essentialBoundsNode) continue; // ignore connecting primitives with no exports if (!ni.isCellInstance() &&!ni.hasExports()) { PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.UNKNOWN || fun == PrimitiveNode.Function.PIN || fun == PrimitiveNode.Function.CONTACT || fun == PrimitiveNode.Function.CONNECT || fun == PrimitiveNode.Function.NODE) continue; } // make a list of all equivalent nodes that match this one if (ni.isIconOfParent()) continue; List<NodeMatch> matches = new ArrayList<NodeMatch>(); for(Iterator<Nodable> noIt = nl.getNodables(); noIt.hasNext(); ) { Nodable no = noIt.next(); if (no.getNodeInst() == ni) { NodeMatch nm = new NodeMatch(ni, no.getName()); nm.findEquivalentByName(toCell); if (nm.otherNi == null) unmatched.add(nm); matches.add(nm); } } nodeMap.put(ni, matches); } // resolve unmatched nodes if (unmatched.size() > 0) { // make a list of unmatched nodes in the "to" cell Set<NodeInst> availableToNodes = new HashSet<NodeInst>(); for(Iterator<NodeInst> it = toCell.getNodes(); it.hasNext(); ) availableToNodes.add(it.next()); for(Iterator<NodeInst> it = fromCell.getNodes(); it.hasNext(); ) { List<NodeMatch> associated = nodeMap.get(it.next()); if (associated == null) continue; for(NodeMatch nm : associated) { if (nm.otherNi != null) availableToNodes.remove(nm.otherNi); } } for(int i=0; i<unmatched.size(); i++) { NodeMatch nm = unmatched.get(i); NodeProto fromNp = nm.ni.getProto(); // make a list of these nodes in the "from" cell List<NodeMatch> fromNm = new ArrayList<NodeMatch>(); for(NodeMatch nmTest : unmatched) { if (nmTest.ni.getProto() == fromNp) fromNm.add(nmTest); } // make a list of these nodes in the "to" cell List<NodeInst> toNi = new ArrayList<NodeInst>(); for(NodeInst ni : availableToNodes) { if (ni.isCellInstance()) { if (fromNp instanceof Cell) { if (((Cell)fromNp).getCellGroup() == ((Cell)ni.getProto()).getCellGroup()) toNi.add(ni); } } else { if (fromNp instanceof PrimitiveNode) { if (nm.ni.getFunction() == ni.getFunction()) toNi.add(ni); } } } // if lists are not the same length, give a warning if (fromNm.size() != toNi.size()) { if (fromNp instanceof Cell) System.out.println("Error: there are " + fromNm.size() + " instances of " + fromNp.describe(false) + " in source and " + toNi.size() + " in destination"); continue; } // sort the rest by position and force matches based on that if (fromNm.size() == 0) continue; Collections.sort(fromNm, new NameMatchSpatially()); Collections.sort(toNi, new InstancesSpatially()); for(int j=0; j<fromNm.size(); j++) { NodeMatch nmAssoc = fromNm.get(j); NodeInst niAssoc = toNi.get(j); nmAssoc.otherNi = niAssoc; unmatched.remove(nmAssoc); availableToNodes.remove(niAssoc); } } } // now construct the unrouted arcs in the "to" cell int wiresMade = 0; for(Iterator<Network> it = nl.getNetworks(); it.hasNext(); ) { Network net = it.next(); Set<PortInst> endSet = new HashSet<PortInst>(); // deal with export matches for(Iterator<Export> eIt = net.getExports(); eIt.hasNext(); ) { Export e = eIt.next(); int eWidth = nl.getBusWidth(e); for(int i=0; i<eWidth; i++) { if (net != nl.getNetwork(e, i)) continue; String eName = e.getNameKey().subname(i).toString(); for(Iterator<Export> oEIt = toCell.getExports(); oEIt.hasNext(); ) { Export oE = oEIt.next(); if (oE.getName().equalsIgnoreCase(eName)) endSet.add(oE.getOriginalPort()); } } } // find all PortInsts on this network for(Iterator<ArcInst> aIt = net.getArcs(); aIt.hasNext(); ) { ArcInst ai = aIt.next(); int busWidth = nl.getBusWidth(ai); for(int b=0; b<busWidth; b++) { Network busNet = nl.getNetwork(ai, b); if (busNet != net) continue; // wire "b" of arc "ai" is on the network: include both ends for(int e=0; e<2; e++) { PortInst pi = ai.getPortInst(e); NodeInst ni = pi.getNodeInst(); List<NodeMatch> possibleNodes = nodeMap.get(ni); if (possibleNodes == null) continue; if (possibleNodes.size() > 1) { PortProto p = pi.getPortProto(); int portWidth = p.getNameKey().busWidth(); if (busWidth == portWidth) { // each wire of the bus connects to the same port on the different arrayed nodes Name portName = p.getNameKey().subname(b); for(NodeMatch nm : possibleNodes) { if (nm.otherNi == null) continue; PortProto pp = nm.otherNi.getProto().findPortProto(portName); PortInst piDest = nm.otherNi.findPortInstFromProto(pp); if (piDest != null) endSet.add(piDest); } } else { // bus is has different signal for each arrayed node int nodeIndex = b / portWidth; int portIndex = b % portWidth; NodeMatch nm = possibleNodes.get(nodeIndex); if (nm.otherNi != null) { Name portName = p.getNameKey().subname(portIndex); PortProto pp = nm.otherNi.getProto().findPortProto(portName); PortInst piDest = nm.otherNi.findPortInstFromProto(pp); if (piDest != null) endSet.add(piDest); } } } else { PortProto p = pi.getPortProto(); int nodeIndex = 0; int portIndex = b; NodeMatch nm = possibleNodes.get(nodeIndex); if (nm.otherNi != null) { Name portName = p.getNameKey().subname(portIndex); PortProto pp = nm.otherNi.getProto().findPortProto(portName); PortInst piDest = nm.otherNi.findPortInstFromProto(pp); if (piDest == null) { if (nm.otherNi.getNumPortInsts() == 1) piDest = nm.otherNi.getOnlyPortInst(); } if (piDest != null) endSet.add(piDest); } } } } } // sort the connections List<PortInst> sortedPorts = new ArrayList<PortInst>(); for(PortInst pi : endSet) sortedPorts.add(pi); Collections.sort(sortedPorts, new PortsByName()); // create the connections PortInst lastPi = null; for(PortInst pi : sortedPorts) { if (lastPi != null) { Poly lPoly = lastPi.getPoly(); Poly poly = pi.getPoly(); Point2D lPt = new Point2D.Double(lPoly.getCenterX(), lPoly.getCenterY()); Point2D pt = new Point2D.Double(poly.getCenterX(), poly.getCenterY()); ArcInst newAi = ArcInst.makeInstance(Generic.tech().unrouted_arc, lastPi, pi, lPt, pt, null); if (newAi == null) break; wiresMade++; } lastPi = pi; } } if (wiresMade == 0) System.out.println("No topology was copied"); else System.out.println("Created " + wiresMade + " arcs to copy the topology"); return true; } private static class PortsByName implements Comparator<PortInst> {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -