📄 cellchangejobs.java
字号:
NodeInst ni = nIt.next(); if (!ni.isCellInstance()) continue; Cell sub = (Cell)ni.getProto(); // ignore recursive references (showing icon in contents) if (ni.isIconOfParent()) continue; CellGraphNode subCgn = cellGraphNodes.get(sub); if (subCgn.depth <= cgn.depth) { subCgn.depth = cgn.depth + 1; if (subCgn.depth > maxDepth) maxDepth = subCgn.depth; more = true; } Cell trueCell = sub.contentsView(); if (trueCell == null) continue; CellGraphNode trueCgn = cellGraphNodes.get(trueCell); if (trueCgn.depth <= cgn.depth) { trueCgn.depth = cgn.depth + 1; if (trueCgn.depth > maxDepth) maxDepth = trueCgn.depth; more = true; } } } } // add in any cells referenced from other libraries if (!more && top == null) { for(Iterator<Cell> cIt = Library.getCurrent().getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth >= 0) continue; cgn.depth = 0; more = true; } } } // now assign X coordinates to each cell maxDepth++; double maxWidth = 0; double [] xval = new double[maxDepth]; double [] yoff = new double[maxDepth]; for(int i=0; i<maxDepth; i++) xval[i] = yoff[i] = 0; for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); CellGraphNode cgn = cellGraphNodes.get(cell); // ignore icon cells from the graph (merge with contents) if (cgn.depth == -1) continue; // ignore associated cells for now Cell trueCell = graphMainView(cell); if (trueCell != null && (cell.getNumUsagesIn() == 0 || cell.isIcon() || cell.getView() == View.LAYOUTSKEL)) { cgn.depth = -1; continue; } cgn.x = xval[cgn.depth]; xval[cgn.depth] += cell.describe(false).length(); if (xval[cgn.depth] > maxWidth) maxWidth = xval[cgn.depth]; cgn.y = cgn.depth; cgn.yoff = 0; } } // now center each row for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth == -1) continue; if (xval[(int)cgn.y] < maxWidth) { double spread = maxWidth / xval[(int)cgn.y]; cgn.x = cgn.x * spread; } } } // generate accurate X/Y coordinates double xScale = 2.0 / 3.0; double yScale = 20; double yOffset = TEXTHEIGHT * 1.25; for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth == -1) continue; double x = cgn.x; double y = cgn.y; x = x * xScale; y = -y * yScale + ((yoff[(int)cgn.y]++)%3) * yOffset; cgn.x = x; cgn.y = y; } } // make unattached cells sit with their contents view if (top == null) { for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth != -1) continue; if (cell.getNumUsagesIn() != 0 && !cell.isIcon() && cell.getView() != View.LAYOUTSKEL) continue; Cell trueCell = graphMainView(cell); if (trueCell == null) continue; CellGraphNode trueCgn = cellGraphNodes.get(trueCell); if (trueCgn.depth == -1) continue; cgn.pin = cgn.topPin = cgn.botPin = null; cgn.main = trueCgn; cgn.yoff += yOffset*2; cgn.x = trueCgn.x; cgn.y = trueCgn.y + trueCgn.yoff; } } } // write the header message double xsc = maxWidth * xScale / 2; NodeInst titleNi = NodeInst.newInstance(Generic.tech().invisiblePinNode, new Point2D.Double(xsc, yScale), 0, 0, graphCell); if (titleNi == null) return false; StringBuffer infstr = new StringBuffer(); if (top != null) { infstr.append("Structure below " + top); } else { infstr.append("Structure of library " + Library.getCurrent().getName()); } TextDescriptor td = TextDescriptor.getNodeTextDescriptor().withRelSize(6); titleNi.newVar(Artwork.ART_MESSAGE, infstr.toString(), td); // place the components for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); if (cell == graphCell) continue; CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth == -1) continue; double x = cgn.x; double y = cgn.y; cgn.pin = NodeInst.newInstance(Generic.tech().invisiblePinNode, new Point2D.Double(x, y), 0, 0, graphCell); if (cgn.pin == null) return false; cgn.topPin = NodeInst.newInstance(Generic.tech().invisiblePinNode, new Point2D.Double(x, y+TEXTHEIGHT/2), 0, 0, graphCell); if (cgn.topPin == null) return false; cgn.botPin = NodeInst.newInstance(Generic.tech().invisiblePinNode, new Point2D.Double(x, y-TEXTHEIGHT/2), 0, 0, graphCell); if (cgn.botPin == null) return false; PortInst pinPi = cgn.pin.getOnlyPortInst(); PortInst toppinPi = cgn.botPin.getOnlyPortInst(); PortInst botPinPi = cgn.topPin.getOnlyPortInst(); ArcInst link1 = ArcInst.makeInstanceBase(Generic.tech().invisible_arc, 0, toppinPi, pinPi); ArcInst link2 = ArcInst.makeInstanceBase(Generic.tech().invisible_arc, 0, pinPi, botPinPi); link1.setRigid(true); link2.setRigid(true); link1.setHardSelect(true); link2.setHardSelect(true); cgn.topPin.setHardSelect(); cgn.botPin.setHardSelect(); // write the cell name in the node TextDescriptor ctd = TextDescriptor.getNodeTextDescriptor().withRelSize(2); cgn.pin.newVar(Artwork.ART_MESSAGE, cell.describe(false), ctd); } } // attach related components with rigid arcs for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); if (cell == graphCell) continue; CellGraphNode cgn = cellGraphNodes.get(cell); if (cgn.depth == -1) continue; if (cgn.main == null) continue; PortInst firstPi = cgn.pin.getOnlyPortInst(); ArcInst ai = ArcInst.makeInstanceBase(Artwork.tech().solidArc, 0, firstPi, firstPi); if (ai == null) return false; ai.setRigid(true); ai.setHardSelect(true); // set an invisible color on the arc ai.newVar(Artwork.ART_COLOR, new Integer(0)); } } // build wires between the hierarchical levels int clock = 0; for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); ) { Library lib = it.next(); if (lib.isHidden()) continue; for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); ) { Cell cell = cIt.next(); if (cell == graphCell) continue; // always use the contents cell, not the icon Cell trueCell = cell.contentsView(); if (trueCell == null) trueCell = cell; CellGraphNode trueCgn = cellGraphNodes.get(trueCell); if (trueCgn.depth == -1) continue; clock++; for(Iterator<NodeInst> nIt = trueCell.getNodes(); nIt.hasNext(); ) { NodeInst ni = nIt.next(); if (!ni.isCellInstance()) continue; // ignore recursive references (showing icon in contents) if (ni.isIconOfParent()) continue; Cell sub = (Cell)ni.getProto(); Cell truesubnp = sub.contentsView(); if (truesubnp == null) truesubnp = sub; CellGraphNode trueSubCgn = cellGraphNodes.get(truesubnp); if (trueSubCgn.clock == clock) continue; trueSubCgn.clock = clock; // draw a line from cell "trueCell" to cell "truesubnp" if (trueSubCgn.depth == -1) continue; PortInst toppinPi = trueCgn.botPin.getOnlyPortInst(); PortInst niBotPi = trueSubCgn.topPin.getOnlyPortInst(); ArcInst ai = ArcInst.makeInstance(Artwork.tech().solidArc, toppinPi, niBotPi); if (ai == null) return false; ai.setRigid(false); ai.setFixedAngle(false); ai.setSlidable(false); ai.setHardSelect(true); // set an appropriate color on the arc (red for jumps of more than 1 level of depth) int color = EGraphics.BLUE; if (trueCgn.y - trueSubCgn.y > yScale+yOffset+yOffset) color = EGraphics.RED; ai.newVar(Artwork.ART_COLOR, new Integer(color)); } } } return true; } public void terminateOK() { // to redraw the new cell UserInterface ui = Job.getUserInterface(); ui.displayCell(graphCell); } } /** * Method to find the main cell that "np" is associated with in the graph. This code is * essentially the same as "contentscell()" except that any original type is allowed. * Returns NONODEPROTO if the cell is not associated. */ private static Cell graphMainView(Cell cell) { // first check to see if there is a schematics link Cell mainSchem = cell.getCellGroup().getMainSchematics(); if (mainSchem != null) return mainSchem; // now check to see if there is any layout link for(Iterator<Cell> it = cell.getCellGroup().getCells(); it.hasNext(); ) { Cell cellInGroup = it.next(); if (cellInGroup.getView() == View.LAYOUT) return cellInGroup; } // finally check to see if there is any "unknown" link for(Iterator<Cell> it = cell.getCellGroup().getCells(); it.hasNext(); ) { Cell cellInGroup = it.next(); if (cellInGroup.getView() == View.UNKNOWN) return cellInGroup; } // no contents found return null; } /****************************** EXTRACT CELL INSTANCES ******************************/ /** * This class implement the command to delete unused old versions of cells. */ public static class PackageCell extends Job { Cell curCell; Set<Geometric> whatToPackage; String newCellName; public PackageCell(Cell curCell, Set<Geometric> whatToPackage, String newCellName) { super("Package Cell", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.curCell = curCell; this.whatToPackage = whatToPackage; this.newCellName = newCellName; startJob(); } public boolean doIt() throws JobException { // create the new cell Cell cell = Cell.makeInstance(Library.getCurrent(), newCellName); if (cell == null) return false; // copy the nodes into the new cell Map<NodeInst,NodeInst> newNodes = new HashMap<NodeInst,NodeInst>(); for(Geometric look : whatToPackage) { if (!(look instanceof NodeInst)) continue; NodeInst ni = (NodeInst)look; String name = null; Name oldName = ni.getNameKey(); if (!oldName.isTempname()) name = oldName.toString(); NodeInst newNi = NodeInst.makeInstance(ni.getProto(), new Point2D.Double(ni.getAnchorCenterX(), ni.getAnchorCenterY()), ni.getXSize(), ni.getYSize(), cell, ni.getOrient(), name, 0); if (newNi == null) return false; newNodes.put(ni, newNi); newNi.copyStateBits(ni); newNi.copyVarsFrom(ni); newNi.copyTextDescriptorFrom(ni, NodeInst.NODE_NAME); // make ports where this nodeinst has them for(Iterator<Export> it = ni.getExports(); it.hasNext(); ) { Export pp = it.next(); PortInst pi = newNi.findPortInstFromProto(pp.getOriginalPort().getPortProto()); Export newPp = Export.newInstance(cell, pi, pp.getName(), pp.getCharacteristic()); if (newPp != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -