⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 letool.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                uniquifier.registerCellsToUniquify(cell, VarContext.globalContext);                // if hierarchy errors, do not replace new cells or set new sizes                if (uniquifier.isHierarchyError() || standardCellArrayError) {                    System.out.println(errBuf);                    System.out.println("Error with hierarchy, please fix first: Standard Cell Sizes Not Updated");                    return false;                } else {                    uniquifier.uniquify(cell, VarContext.globalContext);                }            }            System.out.println("Sizes updated. Sizing Finished.");            fieldVariableChanged("cell");            return true;        }        /**         * Get the standard cell for the given size. The type is based on the current         * node type.         * @param ni the current standard cell node         * @param context the context         * @param targetsize the target size         * @return the standard cell (schematic view)         */        private Cell getStandardCell(NodeInst ni, VarContext context, double targetsize) {            Cell np = null;            if (ni.isCellInstance()) {                np = (Cell)ni.getProto();            }            if (np != null && np.getCellGroup().getMainSchematics().getVar(SCLibraryGen.STANDARDCELL) != null) {                // this is a standard cell from a standard cell library                int tail = np.getName().indexOf("_X");                String type = np.getName().substring(0, tail);                double diff = Double.MAX_VALUE;                double chosensize = 0;                Cell chosencell = null;                for (Iterator<Cell> it = np.getLibrary().getCells(); it.hasNext(); ) {                    Cell c = it.next();                    if (!c.isSchematic()) continue;                    String cname = c.getName();                    if (!cname.startsWith(type+"_X")) continue;                    double size = 0;                    try {                        size = Double.parseDouble(cname.substring(type.length()+2));                    } catch (NumberFormatException e) {                        continue;                    }                    double tempdiff = targetsize - size;                    if (Math.abs(tempdiff) < Math.abs(diff)) {                        diff = tempdiff;                        chosensize = size;                        chosencell = c;                    }                }                if (chosencell == null) {                    System.out.println("Unable to find standard cell for "+ni.describe(false));                    return null;                }                double percentdiff = diff/targetsize;                if (Math.abs(percentdiff) > standardCellErrorTolerancePrint) {                    String p = TextUtils.formatDouble(100*percentdiff, 1);                    String ideal = TextUtils.formatDouble(targetsize, 2);                    String used = TextUtils.formatDouble(chosensize, 2);                    //String strcontext = (context == VarContext.globalContext ? "topcell" : context.getInstPath("."));                    String strcontext = context.push(ni).getInstPath(".");                    System.out.println("  "+p+"%: "+ideal+" (ideal) vs "+used+" (used); for "+strcontext);                }                return chosencell;            }            return null;        }        public void terminateOK() {            EditWindow wnd = EditWindow.findWindow(cell);            if (wnd != null) wnd.fullRepaint();        }    }    /**     * What I really want is to overload VarContext.hashCode to be     * based on the string path, but that is really only valid for this     * particular application, so instead I made a map that uses     * the string path as the key.     */    public static class UniqueNodeMap {        private Map<String,Cell> nodeMap;        public UniqueNodeMap() {            nodeMap = new HashMap<String,Cell>();        }        public void put(VarContext context, Cell cell) {            nodeMap.put(getKey(context), cell);        }        public Cell get(VarContext context) {            return nodeMap.get(getKey(context));        }        public int size() {            return nodeMap.size();        }        private static String getKey(VarContext context) {            return context.getInstPath(".");        }    }    /**     * The Uniquifier does two passes through the hierarchy.     * The first pass is bottom-up to determine which cells need to     * be duplicated/replaced. This depends on which nodes are standard cells     * and what sizes they are.     * The second pass goes top down doing all the actual cell replacements.     * It must be top down to get the replacements correct, as lower level     * cells must be replaced in their properly replaced upper level cells.     */    private static class Uniquifier {        // key: varcontext, value: icon cell for last nodeinst on context        // note that this contains standard cells for replacement, as well as uniquified cells        private UniqueNodeMap uniqueNodeMap;        // Map for a cell in the original hierarchy to it's replacement (unique) cells        private Map<Cell,UniqueCell> uniqueCellMap;        private boolean hierarchyError = false;        private boolean verbose = false;        public Uniquifier(UniqueNodeMap leafCellNodeMap) {            this.uniqueNodeMap = leafCellNodeMap;            uniqueCellMap = new HashMap<Cell,UniqueCell>();        }        /**         * First pass: bottom up check of standard cells in the hierarchy.         * Any cell that contains standard cells, or contains cells that contain         * standard cells, is registered, and checked if it must be made unique.         * A cell instantiated more than once in the design, that contains standard         * cells with different sizes, must be made unique.  This method is         * recursive.         * @param cell current cell         * @param context current context         */        public void registerCellsToUniquify(Cell cell, VarContext context) {            Netlist netlist = cell.getUserNetlist();            for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) {                Nodable no = it.next();                if (!no.isCellInstance()) continue;                Cell subproto = (Cell)no.getProto();                if (subproto.isIconOf(cell)) continue;                Cell schcell = subproto.getCellGroup().getMainSchematics();                // recurse, bottom up                registerCellsToUniquify(schcell, context.push(no));            }            // want bottom up traversal, so do action now after recurse            Map<String,Cell> relevantNodes = new HashMap<String,Cell>();            Map<NodeInst,Cell> arrayedNodeConflicts = new HashMap<NodeInst,Cell>();            for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) {                Nodable no = it.next();                if (!no.isCellInstance()) continue;                VarContext nocontext = context.push(no);                Cell iconCell = uniqueNodeMap.get(nocontext);                if (iconCell == null) continue;                // add to relevant nodes                prMsg("Found Cell "+iconCell.describe(false)+" for context "+nocontext.getInstPath("."));                relevantNodes.put(no.getName(), iconCell);                // check for arrayed node conflicts (all nodes in array must map to same cell)                Cell mappedIconCell = arrayedNodeConflicts.get(no.getNodeInst());                if (mappedIconCell == null) {                    arrayedNodeConflicts.put(no.getNodeInst(), iconCell);                } else if (mappedIconCell != iconCell) {                    System.out.println("ERROR: Arrayed node: "+nocontext.getInstPath("."));                    System.out.println("       Has different sizes or different sizes in sub nodes; array must be flattened");                    hierarchyError = true;                }            }            if (context == VarContext.globalContext) return;            if (relevantNodes.size() > 0) {                // we may need to make this cell unique                UniqueCell uniqueCell = uniqueCellMap.get(cell);                if (uniqueCell == null) {                    // first usage of this cell, do not need to duplicate                    uniqueCell = new UniqueCell(cell, relevantNodes);                    uniqueCellMap.put(cell, uniqueCell);                }                Cell newcell = uniqueCell.getUniqueCell(relevantNodes);                uniqueNodeMap.put(context, newcell.iconView());            }        }        /**         * Second pass: top down replacement of both uniquified cells and         * standard cells.  The replacement must be top down as sub-cells must         * be replaced in their properly replaced parent cells. This method is         * recursive.         * @param cell current cell         * @param context current context         */        public void uniquify(Cell cell, VarContext context) {            Netlist netlist = cell.getUserNetlist();            // top down traversal            for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) {                Nodable no = it.next();                if (!no.isCellInstance()) continue;                NodeInst ni = no.getNodeInst();                Cell subcell = (Cell)no.getProto();                if (subcell.isIconOf(cell)) continue;                VarContext nocontext = context.push(no);                Cell schsubcell = subcell.getCellGroup().getMainSchematics();                Cell newIcon = uniqueNodeMap.get(nocontext);                if (newIcon != null && newIcon != ni.getProto()) {                    if (ni.isLinked()) {                        // if arrayed node, may have already replaced, so only replace if linked                        ni.replace(newIcon, true, true);                        prMsg("Replaced "+nocontext.getInstPath(".")+" with "+newIcon.describe(false));                    }                    schsubcell = newIcon.getCellGroup().getMainSchematics();                    // find new nodable                    boolean found = false;                    for (Iterator<Nodable> it2 = netlist.getNodables(); it2.hasNext(); ) {                        Nodable no2 = it2.next();                        if (no.getNameKey() == no2.getNameKey()) {                            nocontext = context.push(no2);                            found = true;                            break;                        }                    }                    if (!found) {                        System.out.println("ERROR: Could not find new nodable for "+context.getInstPath(".")+"."+no.getName());                    }                }                // recurse, top down                uniquify(schsubcell, nocontext);            }        }        public boolean isHierarchyError() { return hierarchyError; }        public void prMsg(String msg) {            if (verbose) System.out.println(msg);        }    }    /**     * Register a cell containing standard cells, or containing     * cells that contain standard cells - hereafter called the "relevant cells".     * A unique key is made based on the relevant cells. Instances     * with the same key share the same unique cell. The first key is assigned     * to the original cell; new keys are assigned to duplicated cells.     */    private static class UniqueCell {        private Set<String> relevantNodeNames;        private Map<String,Cell> uniqueCells;        private Cell originalCell;        private boolean verbose = false;        private UniqueCell(Cell cell, Map<String,Cell> relevantNodes) {            originalCell = cell;            this.relevantNodeNames = relevantNodes.keySet();            uniqueCells = new HashMap<String,Cell>();            // register existing cell as associated with current set of nodes            String key = getKey(relevantNodes);            uniqueCells.put(key, cell);            prMsg("Registering original cell "+originalCell.describe(false)+" under key "+key);        }        public String getKey(Map<String,Cell> relevantNodes) {            StringBuffer buf = new StringBuffer();            for (String s : relevantNodeNames) {                Cell c = relevantNodes.get(s);                if (c != null) {                    buf.append(c.getLibrary().getName());                    buf.append(c.getName());                }            }            return buf.toString();        }        /**         * Retrieve a unique cell given the relevant nodes at some point in the         * hierarchy. The relevant nodes are mapped to a key. If a cell is already         * associated with the key, it is returned. Otherwise, a cell is duplicated         * from the original cell, associated with the key, and returned.         * @param relevantNodes the nodes that should be used at that point in the hierarchy.         * May be standard cells or unique cells         * @return the unique cells.         */        public Cell getUniqueCell(Map<String,Cell> relevantNodes) {            String key = getKey(relevantNodes);            prMsg("Checking against original cell "+originalCell.describe(false)+" with new key "+key);            Cell c = uniqueCells.get(key);            if (c == null) {                // need to create a new duplicate of cell                c = duplicate(originalCell);                prMsg("Duplicating "+originalCell.describe(false));                uniqueCells.put(key, c);            }            return c;        }        public static Cell duplicate(Cell cell) {            assert cell.isSchematic();            Library lib = cell.getLibrary();            String pname = cell.getName().replaceAll("_[0-9]+$", "");            String newpname = pname;            int i=1;            for (i=1; i<100; i++) {                String temp = pname+"_"+i;                if (lib.findNodeProto(temp) == null) {                    newpname = temp;                    break;                }            }            if (i == 100) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -