📄 circuitchanges.java
字号:
// all arcs must connect in the pin center boolean arcsInCenter = true; for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst ai = con.getArc(); if (ai.getHeadPortInst().getNodeInst() == ni) { if (ai.getHeadLocation().getX() != ni.getAnchorCenterX()) { arcsInCenter = false; break; } if (ai.getHeadLocation().getY() != ni.getAnchorCenterY()) { arcsInCenter = false; break; } } if (ai.getTailPortInst().getNodeInst() == ni) { if (ai.getTailLocation().getX() != ni.getAnchorCenterX()) { arcsInCenter = false; break; } if (ai.getTailLocation().getY() != ni.getAnchorCenterY()) { arcsInCenter = false; break; } } } if (!arcsInCenter) continue; // look for arcs that are oversized double overSizeArc = 0; for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst ai = con.getArc(); double overSize = ai.getLambdaBaseWidth() - ai.getProto().getDefaultLambdaBaseWidth();// double overSize = ai.getLambdaFullWidth() - ai.getProto().getDefaultLambdaFullWidth(); if (overSize < 0) overSize = 0; if (overSize > overSizeArc) overSizeArc = overSize; } // if an arc covers the pin, leave the pin if (overSizeArc >= overSizeX && overSizeArc >= overSizeY) continue; double dSX = 0, dSY = 0; if (overSizeArc < overSizeX) dSX = overSizeX - overSizeArc; if (overSizeArc < overSizeY) dSY = overSizeY - overSizeArc; pinsToScale.put(ni, new EPoint(-dSX, -dSY)); } // look for pins that are invisible and have text in different location List<NodeInst> textToMove = new ArrayList<NodeInst>(); for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); Point2D pt = ni.invisiblePinWithOffsetText(false); if (pt != null) textToMove.add(ni); } // highlight oversize pins that allow arcs to connect without touching int overSizePins = 0; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getFunction() != PrimitiveNode.Function.PIN) continue; // make sure all arcs touch each other boolean nodeIsBad = false; for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); ArcInst ai = con.getArc(); Poly poly = ai.makeLambdaPoly(ai.getGridBaseWidth(), Poly.Type.FILLED); for(Iterator<Connection> oCIt = ni.getConnections(); oCIt.hasNext(); ) { Connection oCon = oCIt.next(); ArcInst oAi = oCon.getArc(); if (ai.getArcId() <= oAi.getArcId()) continue; Poly oPoly = oAi.makeLambdaPoly(oAi.getGridBaseWidth(), Poly.Type.FILLED); double dist = poly.separation(oPoly); if (dist <= 0) continue; nodeIsBad = true; break; } if (nodeIsBad) break; } if (nodeIsBad) { if (justThis) { highlighter.addElectricObject(ni, cell); } overSizePins++; } } // look for duplicate arcs HashSet<ArcInst> arcsToKill = new HashSet<ArcInst>(); for (Iterator<ArcInst> ait = cell.getArcs(); ait.hasNext(); ) { ArcInst ai = ait.next(); int arcId = ai.getArcId(); if (arcsToKill.contains(ai)) continue; PortInst pi = ai.getHeadPortInst(); for (Iterator<Connection> it = pi.getConnections(); it.hasNext(); ) { Connection con = it.next(); ArcInst oAi = con.getArc(); if (oAi.getArcId() >= arcId) continue; if (ai.getProto() != oAi.getProto()) continue; int otherEnd = 1 - con.getEndIndex(); PortInst oPi = oAi.getPortInst(otherEnd); if (oPi != ai.getTailPortInst()) continue; arcsToKill.add(oAi); } }// // look for duplicate arcs// HashMap arcsToKill = new HashMap();// for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )// {// NodeInst ni = it.next();// for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); )// {// Connection con = cIt.next();// ArcInst ai = con.getArc();// int otherEnd = 1 - con.getEndIndex();//// int otherEnd = 0;//// if (ai.getConnection(0) == con) otherEnd = 1;// boolean foundAnother = false;// for(Iterator<Connection> oCIt = ni.getConnections(); oCIt.hasNext(); )// {// Connection oCon = oCIt.next();// ArcInst oAi = oCon.getArc();// if (ai.getArcIndex() <= oAi.getArcIndex()) continue;// if (con.getPortInst().getPortProto() != oCon.getPortInst().getPortProto()) continue;// if (ai.getProto() != oAi.getProto()) continue;// int oOtherEnd = 1 - oCon.getEndIndex();//// int oOtherEnd = 0;//// if (oAi.getConnection(0) == oCon) oOtherEnd = 1;// if (ai.getPortInst(otherEnd).getNodeInst() !=// oAi.getPortInst(oOtherEnd).getNodeInst()) continue;// if (ai.getPortInst(otherEnd).getPortProto() !=// oAi.getPortInst(oOtherEnd).getPortProto()) continue;//// // this arc is a duplicate// arcsToKill.put(oAi, oAi);// foundAnother = true;// break;// }// if (foundAnother) break;// }// } // now highlight negative or zero-size nodes int zeroSize = 0, negSize = 0; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode || ni.getProto() == Generic.tech().invisiblePinNode || ni.getProto() == Generic.tech().universalPinNode || ni.getProto() == Generic.tech().essentialBoundsNode) continue; double sX = ni.getLambdaBaseXSize(); double sY = ni.getLambdaBaseYSize();// SizeOffset so = ni.getSizeOffset();// double sX = ni.getXSize() - so.getLowXOffset() - so.getHighXOffset();// double sY = ni.getYSize() - so.getLowYOffset() - so.getHighYOffset(); if (sX > 0 && sY > 0) continue; if (justThis) { highlighter.addElectricObject(ni, cell); } if (sX < 0 || sY < 0) negSize++; else zeroSize++; } if (pinsToRemove.size() == 0 && pinsToPassThrough.size() == 0 && pinsToScale.size() == 0 && zeroSize == 0 && negSize == 0 && textToMove.size() == 0 && overSizePins == 0 && arcsToKill.size() == 0) { if (justThis) System.out.println("Nothing to clean"); return false; } new CircuitChangeJobs.CleanupChanges(cell, justThis, pinsToRemove, pinsToPassThrough, pinsToScale, textToMove, arcsToKill, zeroSize, negSize, overSizePins); return true; } /** * Method to analyze the current cell and show all nonmanhattan geometry. */ public static void showNonmanhattanCommand() { Cell curCell = WindowFrame.needCurCell(); if (curCell == null) return; WindowFrame wf = WindowFrame.getCurrentWindowFrame(); if (wf == null) return; Highlighter highlighter = wf.getContent().getHighlighter(); if (highlighter == null) return; // see which cells (in any library) have nonmanhattan stuff HashSet<Cell> cellsSeen = new HashSet<Cell>(); for(Iterator<Library> lIt = Library.getLibraries(); lIt.hasNext(); ) { Library lib = lIt.next(); for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); for(Iterator<ArcInst> aIt = cell.getArcs(); aIt.hasNext(); ) { ArcInst ai = aIt.next(); ArcProto ap = ai.getProto(); if (ap.getTechnology() == Generic.tech() || ap.getTechnology() == Artwork.tech() || ap.getTechnology() == Schematics.tech()) continue; Variable var = ai.getVar(ImmutableArcInst.ARC_RADIUS); if (var != null) cellsSeen.add(cell); if (ai.getHeadLocation().getX() != ai.getTailLocation().getX() && ai.getHeadLocation().getY() != ai.getTailLocation().getY()) cellsSeen.add(cell); } for(Iterator<NodeInst> nIt = cell.getNodes(); nIt.hasNext(); ) { NodeInst ni = nIt.next(); if ((ni.getAngle() % 900) != 0) cellsSeen.add(cell); } } } // show the nonmanhattan things in the current cell int i = 0; for(Iterator<ArcInst> aIt = curCell.getArcs(); aIt.hasNext(); ) { ArcInst ai = aIt.next(); ArcProto ap = ai.getProto(); if (ap.getTechnology() == Generic.tech() || ap.getTechnology() == Artwork.tech() || ap.getTechnology() == Schematics.tech()) continue; boolean nonMan = false; Variable var = ai.getVar(ImmutableArcInst.ARC_RADIUS); if (var != null) nonMan = true; if (ai.getHeadLocation().getX() != ai.getTailLocation().getX() && ai.getHeadLocation().getY() != ai.getTailLocation().getY()) nonMan = true; if (nonMan) { if (i == 0) highlighter.clear(); highlighter.addElectricObject(ai, curCell); i++; } } for(Iterator<NodeInst> nIt = curCell.getNodes(); nIt.hasNext(); ) { NodeInst ni = nIt.next(); if ((ni.getAngle() % 900) == 0) continue; if (i == 0) highlighter.clear(); highlighter.addElectricObject(ni, curCell); i++; } if (i == 0) System.out.println("No nonmanhattan objects in this cell"); else { highlighter.finished(); System.out.println(i + " objects are not manhattan in this cell"); } // tell about other non-manhatten-ness elsewhere for(Iterator<Library> lIt = Library.getLibraries(); lIt.hasNext(); ) { Library lib = lIt.next(); if (lib.isHidden()) continue; int numBad = 0; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); if (cellsSeen.contains(cell) && cell != curCell) numBad++; } if (numBad == 0) continue; if (lib == Library.getCurrent()) { int cellsFound = 0; String infstr = ""; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); if (cell == curCell || !cellsSeen.contains(cell)) continue; if (cellsFound > 0) infstr += " ";; infstr += cell.describe(true); cellsFound++; } if (cellsFound == 1) { System.out.println("Found nonmanhattan geometry in cell " + infstr); } else { System.out.println("Found nonmanhattan geometry in these cells: " + infstr); } } else { System.out.println("Found nonmanhattan geometry in " + lib); } } } /** * Method to highlight all pure layer nodes in the current cell. */ public static void showPureLayerCommand() { Cell curCell = WindowFrame.needCurCell(); if (curCell == null) return; WindowFrame wf = WindowFrame.getCurrentWindowFrame(); if (wf == null) return; Highlighter highlighter = wf.getContent().getHighlighter(); if (highlighter == null) return; // show the pure layer nodes in the current cell int i = 0; for(Iterator<NodeInst> nIt = curCell.getNodes(); nIt.hasNext(); ) { NodeInst ni = nIt.next(); if (ni.getFunction() != PrimitiveNode.Function.NODE) continue; if (i == 0) highlighter.clear(); highlighter.addElectricObject(ni, curCell); i++; } if (i == 0) System.out.println("No pure layer nodes in this cell"); else { highlighter.finished(); System.out.println(i + " pure layer nodes in this cell"); } } /** * Method to shorten all selected arcs. * Since arcs may connect anywhere inside of the ports on nodes, a port with nonzero area will allow an arc * to move freely. * This command shortens selected arcs so that their endpoints arrive at the part of the node that allows the shortest arc. */ public static void shortenArcsCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ShortenArcs(cell, MenuCommands.getSelectedArcs()); } /** * Method to show all redundant pure-layer nodes in the Cell. * It works only for rectangular pure-layer nodes that are inside of other * (possibly nonrectangular) nodes. * It works on visible layers only. */ public static void showRedundantPureLayerNodes() { EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Cell cell = WindowFrame.needCurCell(); if (cell == null) return; Set<NodeInst> redundantPures = new HashSet<NodeInst>(); for(Iterator<Layer> it = cell.getTechnology().getLayers(); it.hasNext(); ) { Layer lay = it.next(); if (!lay.isVisible()) continue; PrimitiveNode pNp = lay.getPureLayerNode(); if (pNp == null) continue; // find all pure-layer nodes in the cell List<NodeInst> allPures = new ArrayList<NodeInst>(); Map<NodeInst,Double> pureAreas = new HashMap<NodeInst,Double>(); RTNode root = RTNode.makeTopLevel(); for(Iterator<NodeInst> nIt = cell.getNodes(); nIt.hasNext(); ) { NodeInst ni = nIt.next(); if (ni.getProto() != pNp) continue; allPures.add(ni); Point2D [] points = ni.getTrace(); double area; if (points == null) area = ni.getXSize() * ni.getYSize(); else { boolean hasGaps = false; for(int i=0; i<points.length; i++) if (points[i] == null) { hasGaps = true; break; } if (hasGaps) { // outline has multiple disjoint polygons area = 0; int start = 0; for(int i=0; i<points.length; i++) { if (i == points.length-1 || points[i+1] == null) { Point2D [] segment = new Point2D[i-start+1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -