📄 layercoveragetool.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: LayerCoverageTool.java * * Copyright (c) 2005 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.extract;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.GeometryHandler;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.HierarchyEnumerator;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.Pref;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.VarContext;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.DRCTemplate;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.TransistorSize;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.Tool;import com.sun.electric.tool.drc.DRC;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.tool.user.User;import java.awt.Shape;import java.awt.geom.AffineTransform;import java.awt.geom.Area;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;/** * Class to describe coverage percentage for a layer. */public class LayerCoverageTool extends Tool{ /** the LayerCoverageTool tool. */ protected static LayerCoverageTool tool = new LayerCoverageTool(); /** * The constructor sets up the DRC tool. */ private LayerCoverageTool() { super("coverage"); } /** * Method to retrieve the singleton associated with the LayerCoverageTool tool. * @return the LayerCoverageTool tool. */ public static LayerCoverageTool getLayerCoverageTool() { return tool; } /****************************** OPTIONS ******************************/ // Default value is in um to be technology independent private static final double defaultSize = 50000; private static Pref cacheDeltaX = Pref.makeDoublePref("DeltaX", tool.prefs, defaultSize); /** * Method to get user preference for deltaX. * The default is 50 mm. * @return double representing deltaX. */ public static double getDeltaX(Technology tech) { return cacheDeltaX.getDouble()/tech.getScale(); } /** * Method to set user preference for deltaX. * @param delta double representing new deltaX. */ public static void setDeltaX(double delta, Technology tech) { cacheDeltaX.setDouble(delta*tech.getScale()); } /** * Method to get user preference for deltaX, by default. * @return double representing deltaX, by default. */ public static double getFactoryDeltaX(Technology tech) { return cacheDeltaX.getDoubleFactoryValue()/tech.getScale(); } private static Pref cacheDeltaY = Pref.makeDoublePref("DeltaY", tool.prefs, defaultSize); /** * Method to get user preference for deltaY. * The default is 50 mm. * @return double representing deltaY. */ public static double getDeltaY(Technology tech) { return cacheDeltaY.getDouble()/tech.getScale(); } /** * Method to set user preference for deltaY. * @param delta double representing new deltaY. */ public static void setDeltaY(double delta, Technology tech) { cacheDeltaY.setDouble(delta*tech.getScale()); } /** * Method to get user preference for deltaY, by default. * @return double representing deltaY, by default. */ public static double getFactoryDeltaY(Technology tech) { return cacheDeltaY.getDoubleFactoryValue()/tech.getScale(); } private static Pref cacheWidth = Pref.makeDoublePref("Width", tool.prefs, defaultSize); /** * Method to get user preference for deltaY. * The default is 50 mm. * @return double representing deltaY. */ public static double getWidth(Technology tech) { return cacheWidth.getDouble()/tech.getScale(); } /** * Method to set user preference for width of the bounding box. * @param w double representing new width. */ public static void setWidth(double w, Technology tech) { cacheWidth.setDouble(w*tech.getScale()); } /** * Method to get user preference for deltaY, by default. * @return double representing deltaY, by default. */ public static double getFactoryWidth(Technology tech) { return cacheWidth.getDoubleFactoryValue()/tech.getScale(); } private static Pref cacheHeight = Pref.makeDoublePref("Height", tool.prefs, defaultSize); /** * Method to get user preference for deltaY. * The default is 50 mm. * @return double representing deltaY. */ public static double getHeight(Technology tech) { return cacheHeight.getDouble()/tech.getScale(); } /** * Method to set user preference for height of the bounding box. * @param h double representing new width. */ public static void setHeight(double h, Technology tech) { cacheHeight.setDouble(h*tech.getScale()); } /** * Method to get user preference for deltaY, by default. * @return double representing deltaY, by default. */ public static double getFactoryHeight(Technology tech) { return cacheHeight.getDoubleFactoryValue()/tech.getScale(); } /** * Method to handle the "List Layer Coverage", "Coverage Implant Generator", polygons merge * except "List Geometry on Network" commands. */ public static List<Object> layerCoverageCommand(LCMode func, GeometryHandler.GHMode mode, Cell curCell, boolean startJob) { // Must be change job for merge and implant; Job.Type jobType = (func == LayerCoverageTool.LCMode.MERGE || func == LayerCoverageTool.LCMode.IMPLANT) ? Job.Type.CHANGE : Job.Type.EXAMINE; LayerCoverageJob job = new LayerCoverageJob(curCell, jobType, func, mode, null, null); if (startJob) job.startJob(); else { try { job.doIt(); } catch (Exception e) {} return job.nodesAdded; } return null; } /** * Method to kick area coverage per layer in a cell. It has to be public due to regressions. * @param cell * @param mode * @param startJob to determine if job has to run in a separate thread * @return true if job runs without errors. Only valid if startJob is false (regression purpose) */ public static Map<Layer,Double> layerCoverageCommand(Cell cell, GeometryHandler.GHMode mode, boolean startJob) { if (cell == null) return null; double width = getWidth(cell.getTechnology()); double height = getHeight(cell.getTechnology()); double deltaX = getDeltaX(cell.getTechnology()); double deltaY = getDeltaY(cell.getTechnology()); // Reset values to cell bounding box if area is bigger than the actual cell Rectangle2D bbox = cell.getBounds(); if (width > bbox.getWidth()) width = bbox.getWidth(); if (height > bbox.getHeight()) height = bbox.getHeight(); Map<Layer,Double> map = null; AreaCoverageJob job = new AreaCoverageJob(cell, mode, width, height, deltaX, deltaY); // No regression if (startJob) job.startJob(); else { try { job.doIt(); map = job.getDataInfo(); } catch (JobException e) { } } return (map); } /** * Method to extract bounding box for a particular Network/Layer * @param exportCell * @return Rectangle2D containing the bounding box for a particular Network/Layer */ public static Rectangle2D getGeometryOnNetwork(Cell exportCell, PortInst pi, Layer layer) { Netlist netlist = exportCell.getNetlist(); Network net = netlist.getNetwork(pi); Set<Network> nets = new HashSet<Network>(); nets.add(net); GeometryOnNetwork geoms = new GeometryOnNetwork(exportCell, nets, 1.0, false, layer); // This assumes that pi.getBounds() alywas gives you a degenerated rectangle (zero area) so // only a point should be searched. Rectangle2D bnd = pi.getBounds(); LayerCoverageJob job = new LayerCoverageJob(exportCell, Job.Type.EXAMINE, LCMode.NETWORK, GeometryHandler.GHMode.ALGO_SWEEP, geoms, new Point2D.Double(bnd.getX(), bnd.getY())); // Must run it now try { job.doIt(); // Former listGeometryOnNetworksNoJob } catch (JobException e) { e.printStackTrace(); } List<Object> list = job.nodesAdded; // Don't know what to do if there is more than one Rectangle2D rect = null; if (list.size() != 1) System.out.println("Problem here");// assert(list.size() == 1); else { PolyBase poly = (PolyBase)list.toArray()[0]; rect = poly.getBounds2D(); } return rect; } /** * Method to calculate area, half-perimeter and ratio of each layer by merging geometries * @param cell cell to analyze * @param nets networks to analyze * @param startJob if job has to run on thread * @param mode geometric algorithm to use: GeometryHandler.ALGO_QTREE, GeometryHandler.SWEEP or GeometryHandler.ALGO_MERGE */ public static GeometryOnNetwork listGeometryOnNetworks(Cell cell, Set<Network> nets, boolean startJob, GeometryHandler.GHMode mode) { if (cell == null || nets == null || nets.isEmpty()) return null; double lambda = 1; // lambdaofcell(np); // startJob is identical to printable GeometryOnNetwork geoms = new GeometryOnNetwork(cell, nets, lambda, startJob, null); Job job = new LayerCoverageJob(cell, Job.Type.EXAMINE, LCMode.NETWORK, mode, geoms, null); if (startJob) job.startJob(); else { try { job.doIt(); // Former listGeometryOnNetworksNoJob } catch (JobException e) { } } return geoms; } /************************************************************************ * LayerCoverageData Class ************************************************************************/ private static class LayerCoverageData { private Cell curCell; private Job parentJob; // to stop if parent job is killed private LCMode function; private GeometryHandler.GHMode mode; private GeometryOnNetwork geoms; // Valid only for network job private Rectangle2D bBox; // To crop geometry under analysis by given bounding box private List<Object> nodesToExamine = new ArrayList<Object>(); // for implant private Point2D overlapPoint; // to detect if obtained geometry is connected to original request, // Network in fill generator LayerCoverageData(Job parentJob, Cell cell, LCMode func, GeometryHandler.GHMode mode, GeometryOnNetwork geoms, Rectangle2D bBox, Point2D overlapPoint) { this.parentJob = parentJob; this.curCell = cell; this.mode = mode; this.function = func; this.geoms = geoms; // Valid only for network this.bBox = bBox; this.overlapPoint = overlapPoint; if (func == LCMode.AREA && this.geoms == null) this.geoms = new GeometryOnNetwork(curCell, null, 1, true, null); } List<Object> getNodesToHighlight() { return nodesToExamine; } boolean doIt() { GeometryHandler tree = GeometryHandler.createGeometryHandler(mode, curCell.getTechnology().getNumLayers()); Map<Layer,Set<PolyBase>> originalPolygons = new HashMap<Layer,Set<PolyBase>>(); // Storing initial nodes Set<NodeInst> nodesToDelete = new HashSet<NodeInst>(); // should only be used by IMPLANT Set<Network> netSet = null; Layer onlyThisLayer = null; Netlist.ShortResistors shortResistors = Netlist.ShortResistors.NO; if (geoms != null) { netSet = geoms.nets; if (geoms.nets != null && !geoms.nets.isEmpty()) { Iterator<Network> nIt = geoms.nets.iterator(); shortResistors = nIt.next().getNetlist().getShortResistors(); while (nIt.hasNext()) { Netlist.ShortResistors sh = nIt.next().getNetlist().getShortResistors(); if (sh != shortResistors) throw new IllegalArgumentException("shortResistors"); } } onlyThisLayer = geoms.onlyThisLayer; } // enumerate the hierarchy below here LayerVisitor visitor = new LayerVisitor(parentJob, tree, nodesToDelete, function, originalPolygons, netSet, bBox, onlyThisLayer, geoms);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -