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

📄 layercoveragetool.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            HierarchyEnumerator.enumerateCell(curCell, VarContext.globalContext, visitor, shortResistors);            tree.postProcess(true);            switch (function)            {                case MERGE:                case IMPLANT:                    {                        // With polygons collected, new geometries are calculated                        boolean noNewNodes = true;                        boolean isMerge = (function == LCMode.MERGE);                        Rectangle2D rect;                        Point2D [] points;                        // Need to detect if geometry was really modified                        for (Layer layer : tree.getKeySet())                        {                            Collection<PolyBase> set = tree.getObjects(layer, !isMerge, true);                            Set<PolyBase> polySet = (function == LCMode.IMPLANT) ? originalPolygons.get(layer) : null;                            List<Rectangle2D> newImplants = new ArrayList<Rectangle2D>();                            // Ready to create new implants.                            for (PolyBase polyB : set)                            {                                points = polyB.getPoints();                                rect = polyB.getBounds2D();                                // One of the original elements                                if (polySet != null)                                {                                    Object[] array = polySet.toArray();                                    boolean foundOrigPoly = false;                                    for (Object poly : array)                                    {                                        foundOrigPoly = polyB.polySame((PolyBase)poly);                                        if (foundOrigPoly)                                            break;                                    }                                    if (foundOrigPoly)                                        continue;                                }                                if (isMerge)                                {                                    // Adding the new implant. New implant not assigned to any local variable                                    Point2D center = new Point2D.Double(rect.getCenterX(), rect.getCenterY());                                    PrimitiveNode priNode = layer.getPureLayerNode();                                    NodeInst node = NodeInst.makeInstance(priNode, center, rect.getWidth(), rect.getHeight(), curCell);                                    nodesToExamine.add(node);                                    EPoint [] ePoints = new EPoint[points.length];                                    for(int j=0; j<points.length; j++)                                        ePoints[j] = new EPoint(points[j].getX(), points[j].getY());                                    node.setTrace(ePoints);                                }                                else                                {                                	newImplants.add(rect);                                }                                noNewNodes = false;                            }                            if (function == LCMode.IMPLANT)                            {                            	// merge when close to avoid notch errors            					DRCTemplate rule = DRC.getSpacingRule(layer, null, layer, null, false, -1, 10, 100);            					if (rule != null)            					{            						double dist = rule.getValue(0);            						for(int i=0; i<newImplants.size(); i++)            						{            							Rectangle2D r = newImplants.get(i);            							boolean merged = false;            							for(int j=i+1; j<newImplants.size(); j++)            							{            								Rectangle2D oR = newImplants.get(j);            								if (r.getMinX()-dist > oR.getMaxX() ||            									oR.getMinX()-dist > r.getMaxX() ||            									r.getMinY()-dist > oR.getMaxY() ||            									oR.getMinY()-dist > r.getMaxY()) continue;            								// they are too close: merge them            								double lx = Math.min(r.getMinX(), oR.getMinX());            								double hx = Math.max(r.getMaxX(), oR.getMaxX());            								double ly = Math.min(r.getMinY(), oR.getMinY());            								double hy = Math.max(r.getMaxY(), oR.getMaxY());            								r.setRect(lx, ly, hx-lx, hy-ly);            								newImplants.remove(j);            								merged = true;            								break;            							}            							if (merged) i--;            						}            					}                                PrimitiveNode priNode = layer.getPureLayerNode();                            	for(Rectangle2D r : newImplants)                            	{                            		// TODO Do not create if it is covered by original geometry                                    Point2D center = new Point2D.Double(r.getCenterX(), r.getCenterY());                                    NodeInst node = NodeInst.makeInstance(priNode, center, r.getWidth(), r.getHeight(), curCell);                                    nodesToExamine.add(node);                                    node.setHardSelect();                            	}                            }                        }                        curCell.killNodes(nodesToDelete);                        if (noNewNodes)                            System.out.println("No new areas added");                    }                    break;                case AREA:                case NETWORK:                    {                        double lambdaSqr = 1; // lambdaofcell(np);                        Rectangle2D bbox = curCell.getBounds();                        double totalArea =  (bbox.getHeight()*bbox.getWidth())/lambdaSqr;                        // Traversing tree with merged geometry and sorting layers per name first                        List<Layer> list = new ArrayList<Layer>(tree.getKeySet());                        Collections.sort(list, Layer.layerSortByName);                        for (Layer layer : list)                        {                            Collection<PolyBase> set = tree.getObjects(layer, false, true);                            if (geoms != null && geoms.onlyThisLayer != null)                            {                                if (layer != geoms.onlyThisLayer) continue; // ignore this layer                                // Add all elements                                if (overlapPoint == null)                                    nodesToExamine.addAll(set);                                else                                {                                    // they must be connected                                    for (PolyBase p : set)                                    {                                        if (p.contains(overlapPoint))                                            nodesToExamine.add(p);                                    }                                }                            }                            double layerArea = 0;                            double perimeter = 0;                            // Get all objects and sum the area                            for (PolyBase poly : set)                            {                                layerArea += poly.getArea();                                perimeter += poly.getPerimeter();                            }                            layerArea /= lambdaSqr;                            perimeter /= 2;                            if (geoms != null)                                geoms.addLayer(layer, layerArea, perimeter);                            else                                System.out.println("Layer " + layer.getName() + " covers " + TextUtils.formatDouble(layerArea)                                        + " square lambda (" + TextUtils.formatDouble((layerArea/totalArea)*100, 2) + "%)");                        }                        geoms.setTotalArea(totalArea);                        if (geoms != null)                            geoms.print();                        else                            System.out.println("Cell is " + TextUtils.formatDouble(totalArea, 2) + " square lambda");                    }                    break;                default:                    System.out.println("Error in LayerCoverage: function not implemented");            }            return true;        }    }    /************************************************************************     * LayerCoverageJob Class     ************************************************************************/    private static class LayerCoverageJob extends Job    {        private Cell cell;        private LCMode func;        private GeometryHandler.GHMode mode;        private GeometryOnNetwork geoms;        private List<Object> nodesAdded;        private Point2D overlapPoint; // to get to crop the search if a given bbox is not null        public LayerCoverageJob(Cell cell, Job.Type jobType, LCMode func, GeometryHandler.GHMode mode,                                GeometryOnNetwork geoms, Point2D overlapPoint)        {            super("Layer Coverage on " + cell, User.getUserTool(), jobType, null, null, Priority.USER);            this.cell = cell;            this.func = func;            this.mode = mode;            this.geoms = geoms;            this.overlapPoint = overlapPoint;            setReportExecutionFlag(true);        }        public boolean doIt() throws JobException        {            LayerCoverageData data = new LayerCoverageData(this, cell, func, mode, geoms, null, overlapPoint);            boolean done = data.doIt();            if (func == LCMode.IMPLANT || (func == LCMode.NETWORK && geoms != null))            {                nodesAdded = new ArrayList<Object>();                nodesAdded.addAll(data.getNodesToHighlight());                if (func == LCMode.IMPLANT)                	fieldVariableChanged("nodesAdded");            }            return done;        }        public void terminateOK()        {            // For implant highlight the new nodes            if (func == LCMode.IMPLANT)            {                EditWindow_ wnd = Job.getUserInterface().getCurrentEditWindow_();                if (wnd == null) return; // no GUI present                if (nodesAdded == null) return; // nothing to show                for (Object node : nodesAdded)                {                    wnd.addElectricObject((NodeInst)node, cell);                }            }        }    }    /************************************************************************     * AreaCoverageJob Class     ************************************************************************/    private static class AreaCoverageJob extends Job    {        private Cell curCell;        private double deltaX, deltaY;        private double width, height;        private GeometryHandler.GHMode mode;        private Map<Layer,Double> internalMap;        public AreaCoverageJob(Cell cell, GeometryHandler.GHMode mode,                               double width, double height, double deltaX, double deltaY)        {            super("Layer Coverage", User.getUserTool(), Type.EXAMINE, null, null, Priority.USER);            this.curCell = cell;            this.mode = mode;            this.width = width;            this.height = height;            this.deltaX = deltaX;            this.deltaY = deltaY;            setReportExecutionFlag(true); // Want to report statistics        }        public boolean doIt() throws JobException        {            ErrorLogger errorLogger = ErrorLogger.newInstance("Area Coverage");            Rectangle2D bBoxOrig = curCell.getBounds();            double maxY = bBoxOrig.getMaxY();            double maxX = bBoxOrig.getMaxX();            // if negative or zero values -> only once            if (deltaX <= 0) deltaX = bBoxOrig.getWidth();            if (deltaY <= 0) deltaY = bBoxOrig.getHeight();            if (width <= 0) width = bBoxOrig.getWidth();            if (height <= 0) height = bBoxOrig.getHeight();            internalMap = new HashMap<Layer,Double>();//            fieldVariableChanged("internalMap");            for (double posY = bBoxOrig.getMinY(); posY < maxY; posY += deltaY)            {                for (double posX = bBoxOrig.getMinX(); posX < maxX; posX += deltaX)                {                    Rectangle2D box = new Rectangle2D.Double(posX, posY, width, height);                    GeometryOnNetwork geoms = new GeometryOnNetwork(curCell, null, 1, true, null);                    System.out.println("Calculating Coverage on cell '" + curCell.getName() + "' for area (" +                            DBMath.round(posX) + "," + DBMath.round(posY) + ") (" +                            DBMath.round(box.getMaxX()) + "," + DBMath.round(box.getMaxY()) + ")");                    LayerCoverageData data = new LayerCoverageData(this, curCell, LCMode.AREA, mode, geoms, box, null);                    if (!data.doIt())  // aborted by user                    {                        return false; // didn't finish                    }                    geoms.analyzeCoverage(box, errorLogger);                    for (int i = 0; i < geoms.layers.size(); i++)                    {                        Layer layer = geoms.layers.get(i);                        Double area = geoms.areas.get(i);                        Double oldV = internalMap.get(layer);                        double newV = area.doubleValue();                        if (oldV != null)                            newV += oldV.doubleValue();                        internalMap.put(layer, new Double(newV));                    }                }            }            errorLogger.termLogging(true);            return true;        }        public Map<Layer,Double> getDataInfo() { return internalMap; }    }    public enum LCMode // LC = LayerCoverageTool mode    {	    AREA,   // function Layer Coverage	    MERGE,  // Generic merge polygons function	    IMPLANT, // Coverage implants	    NETWORK // List Geometry on Network function    }    /************************************************************************     * LayerVisitor Class     ************************************************************************/    public static class LayerVisitor extends HierarchyEnumerator.Visitor	{        private Job parentJob;		private GeometryHandler tree;		private Set<NodeInst> deleteList; // Only used for coverage Implants. New coverage implants are pure primitive nodes		private final LCMode function;		private Map<Layer,Set<PolyBase>> originalPolygons;		private Set<Network> netSet; // For network type, rest is null        private Rectangle2D origBBox;        private Area origBBoxArea;   // Area is always in coordinates of top cell        private Layer onlyThisLayer;        private GeometryOnNetwork geoms;		public LayerVisitor(Job job, GeometryHandler t, Set<NodeInst> delList, LCMode func,			Map<Layer, Set<PolyBase>> original, Set<Network> netSet, Rectangle2D bBox, Layer onlyThisLayer, GeometryOnNetwork geoms)		{            this.parentJob = job;			this.tree = t;			this.deleteList = delList;			this.function = func;			this.originalPolygons = original;			this.netSet = netSet;            this.origBBox = bBox;            origBBoxArea = (bBox != null) ? new Area(origBBox) : null;            this.onlyThisLayer = onlyThisLayer;            this.geoms = geoms;		}		/**		 * Determines if function of given layer is applicable for the corresponding operation		 */		private boolean isValidFunction(Layer layer, LCMode function)		{            if (onlyThisLayer != null && layer != onlyThisLayer)                return false;            Layer.Function func = layer.getFunction();			switch (function)			{                case MERGE:				case NETWORK:					return (true);				case IMPLANT:					return (func.isSubstrate());				case AREA:					return (func.isPoly() || func.isMetal());				default:					return (false);			}		}        /**         * In case of non null bounding box, it will undo the         * transformation         * @param info         */		public void exitCell(HierarchyEnumerator.CellInfo info)        {        }        private boolean doesIntersectBoundingBox(Rectangle2D rect, HierarchyEnumerator.CellInfo info)        {            // Default case when no bounding box is used to crop the geometry            if (origBBox == null) return true;            // only because I need to transform the points.            PolyBase polyRect = new PolyBase(rect);            // To avoid transformation while traversing the hierarchy            polyRect.transform(info.getTransformToRoot());            rect = polyRect.getBounds2D();            return rect.intersects(origBBox);        }        private boolean isJobAborted()        {            return (parentJob != null && parentJob.checkAbort());        }        public boolean enterCell(HierarchyEnumerator.CellInfo info)		{

⌨️ 快捷键说明

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