📄 connectivity.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Connectivity.java * Module to do node extraction (extract connectivity from a pure-layout cell) * Written by Steven M. Rubin, Sun Microsystems. * * 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.Dimension2D;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.geometry.PolyMerge;import com.sun.electric.database.geometry.GenMath.MutableBoolean;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;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.topology.RTBounds;import com.sun.electric.database.topology.RTNode;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;import com.sun.electric.technology.Technology.NodeLayer;import com.sun.electric.technology.Technology.TechPoint;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.routing.AutoStitch;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.tool.user.Highlight2;import com.sun.electric.tool.user.dialogs.EDialog;import com.sun.electric.tool.user.ui.TopLevel;import java.awt.Frame;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.regex.Matcher;import java.util.regex.Pattern;import java.util.regex.PatternSyntaxException;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;/** * This is the Connectivity extractor. * * Still need to handle nonmanhattan contacts */public class Connectivity{ /** true to prevent objects smaller than minimum size */ private static final boolean ENFORCEMINIMUMSIZE = false; /** amount to scale values before merging */ private static final double SCALEFACTOR = DBMath.GRID; /** true to debug centerline determination */ private static final boolean DEBUGCENTERLINES = false; /** true to debug object creation */ private static final boolean DEBUGSTEPS = false; /** the current technology for extraction */ private Technology tech; /** layers to use for given arc functions */ private Map<Layer.Function,Layer> layerForFunction; /** the layer to use for "polysilicon" geometry */ private Layer polyLayer; /** temporary layers to use for geometric manipulation */ private Layer tempLayer1; /** the layers to use for "active" geometry */ private Layer pActiveLayer, nActiveLayer; /** associates arc prototypes with layers */ private Map<Layer,ArcProto> arcsForLayer; /** map of extracted cells */ private Map<Cell,Cell> convertedCells; /** map of cut layers to lists of polygons on that layer */ private Map<Layer,List<PolyBase>> allCutLayers; /** set of pure-layer nodes that are not processed */ private Set<PrimitiveNode> ignoreNodes; /** set of contacts that are not used for extraction */ private Set<PrimitiveNode> bogusContacts; /** list of Exports to restore after extraction */ private List<Export> exportsToRestore; /** true if this is a P-well process (presume P-well) */ private boolean pWellProcess; /** true if this is a N-well process (presume N-well) */ private boolean nWellProcess; /** true to unify N and P active layers */ private boolean unifyActive; /** true to ignore select/well around active layers */ private boolean ignoreActiveSelectWell; /** the smallest polygon acceptable for merging */ private double smallestPoly; /** debugging: list of objects created */ private List<ERectangle> addedRectangles; /** debugging: list of objects created */ private List<ERectangle> addedLines; /** list of exported pins to realize at the end */ private List<ExportedPin> pinsForLater; /** ErrorLogger to keep up with errors during extraction */ private ErrorLogger errorLogger; /** Job that is holding the process */ private Job job; /** * Method to examine the current cell and extract it's connectivity in a new one. * @param recursive true to recursively extract the hierarchy below this cell. */ public static void extractCurCell(boolean recursive) { Cell curCell = Job.getUserInterface().needCurrentCell(); if (curCell == null) { System.out.println("Must be editing a cell with pure layer nodes."); return; } new ExtractJob(curCell, recursive); } private static class ExtractJob extends Job { private Cell cell, newCell; private boolean recursive; /** debugging: list of objects created */ private List<List<ERectangle>> addedBatchRectangles; /** debugging: list of objects created */ private List<List<ERectangle>> addedBatchLines; /** debugging: list of objects created */ private List<String> addedBatchNames; /** */ private ErrorLogger errorLogger; private ExtractJob(Cell cell, boolean recursive) { super("Extract Connectivity from " + cell, Extract.getExtractTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.cell = cell; this.recursive = recursive; this.errorLogger = ErrorLogger.newInstance("Extraction Tool on cell " + cell.getName()); startJob(); } public boolean doIt() throws JobException { Connectivity c = new Connectivity(cell, this, errorLogger); String expansionPattern = Extract.getCellExpandPattern().trim(); Pattern pat = null; if (expansionPattern.length() > 0) { try { pat = Pattern.compile(expansionPattern, Pattern.CASE_INSENSITIVE); } catch(PatternSyntaxException e) { System.out.println("Pattern syntax error on '" + expansionPattern + "': " + e.getMessage()); } } if (DEBUGSTEPS) { addedBatchRectangles = new ArrayList<List<ERectangle>>(); addedBatchLines = new ArrayList<List<ERectangle>>(); addedBatchNames = new ArrayList<String>(); } Job.getUserInterface().startProgressDialog("Extracting", null); newCell = c.doExtract(cell, recursive, pat, true, this, addedBatchRectangles, addedBatchLines, addedBatchNames); Job.getUserInterface().stopProgressDialog(); fieldVariableChanged("addedBatchRectangles"); fieldVariableChanged("addedBatchLines"); fieldVariableChanged("addedBatchNames"); fieldVariableChanged("newCell"); fieldVariableChanged("errorLogger"); return true; } public void terminateOK() { UserInterface ui = Job.getUserInterface(); EditWindow_ wnd = ui.displayCell(newCell); Job.getUserInterface().termLogging(errorLogger, false, false); if (DEBUGSTEPS) { // show results of each step JFrame jf = null; if (!TopLevel.isMDIMode()) jf = TopLevel.getCurrentJFrame(); ShowExtraction theDialog = new ShowExtraction(jf, addedBatchRectangles, addedBatchLines, addedBatchNames); theDialog.setVisible(true); } else { // highlight pure layer nodes if (newCell != null) // cell is null if job was aborted { for(Iterator<NodeInst> it = newCell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.NODE) wnd.addElectricObject(ni, newCell); } } else System.out.println("Extraction job was aborted"); } } } /** * Constructor to initialize connectivity extraction. * @param tech the Technology to extract to. */ private Connectivity(Cell cell, Job j, ErrorLogger eLog) { tech = cell.getTechnology(); convertedCells = new HashMap<Cell,Cell>(); smallestPoly = (SCALEFACTOR * SCALEFACTOR) * Extract.getSmallestPolygonSize(); bogusContacts = new HashSet<PrimitiveNode>(); errorLogger = eLog; job = j; // find pure-layer nodes that are never involved in higher-level components, and should be ignored ignoreNodes = new HashSet<PrimitiveNode>(); for(Iterator<PrimitiveNode> pIt = tech.getNodes(); pIt.hasNext(); ) { PrimitiveNode np = pIt.next(); if (np.getFunction() != PrimitiveNode.Function.NODE) continue; Technology.NodeLayer [] nLays = np.getLayers(); boolean validLayers = false; for(int i=0; i<nLays.length; i++) { Technology.NodeLayer nLay = nLays[i]; Layer.Function fun = nLay.getLayer().getFunction(); if (fun == Layer.Function.UNKNOWN || fun == Layer.Function.OVERGLASS || fun == Layer.Function.GUARD || fun == Layer.Function.ISOLATION || fun == Layer.Function.BUS || fun == Layer.Function.ART || fun == Layer.Function.CONTROL || fun == Layer.Function.TILENOT) continue; validLayers = true; } if (!validLayers) ignoreNodes.add(np); } // see how active layers should be handled int activeHandling = Extract.getActiveHandling(); unifyActive = (activeHandling == 1); ignoreActiveSelectWell = (activeHandling == 2); if (!unifyActive) { boolean haveNActive = false, havePActive = false; for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.isCellInstance()) continue; Poly[] polys = ni.getProto().getTechnology().getShapeOfNode(ni); for(int i=0; i<polys.length; i++) { Layer layer = polys[i].getLayer(); if (layer == null) continue; if (!layer.getFunction().isDiff()) continue; if (layer.getFunction() == Layer.Function.DIFFN) haveNActive = true; if (layer.getFunction() == Layer.Function.DIFFP) havePActive = true; } if (haveNActive && havePActive) break; } if (!haveNActive || !havePActive) { System.out.println("Found only one type of active layer...unifying all active layers"); unifyActive = true; } } // find important layers polyLayer = null; pActiveLayer = nActiveLayer = null; for(Iterator<Layer> it = tech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); Layer.Function fun = layer.getFunction(); if (polyLayer == null && fun == Layer.Function.POLY1) polyLayer = layer; if (unifyActive) { if (pActiveLayer == null && fun.isDiff()) pActiveLayer = layer; } else { if (pActiveLayer == null && fun == Layer.Function.DIFFP) pActiveLayer = layer; if (nActiveLayer == null && fun == Layer.Function.DIFFN) nActiveLayer = layer; } } polyLayer = polyLayer.getNonPseudoLayer(); if (polyLayer != null) tempLayer1 = polyLayer.getPseudoLayer(); pActiveLayer = pActiveLayer.getNonPseudoLayer(); if (unifyActive) nActiveLayer = pActiveLayer; else nActiveLayer = nActiveLayer.getNonPseudoLayer(); // figure out which arcs to use for a layer arcsForLayer = new HashMap<Layer,ArcProto>(); for(Iterator<Layer> it = tech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); Layer.Function fun = layer.getFunction(); if (fun.isDiff() || fun.isPoly() || fun.isMetal()) { ArcProto.Function oFun = null; if (fun.isMetal()) oFun = ArcProto.Function.getMetal(fun.getLevel()); if (fun.isPoly()) oFun = ArcProto.Function.getPoly(fun.getLevel()); if (oFun == null) continue; ArcProto type = null; for(Iterator<ArcProto> aIt = tech.getArcs(); aIt.hasNext(); ) { ArcProto ap = aIt.next(); if (ap.getFunction() == oFun) { type = ap; break; } } if (type != null) arcsForLayer.put(layer, type); } } // build the mapping from any layer to the proper ones for the geometric database layerForFunction = new HashMap<Layer.Function,Layer>(); for(Iterator<Layer> it = tech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); Layer.Function fun = layer.getFunction(); if (unifyActive) { if (fun == Layer.Function.DIFFP || fun == Layer.Function.DIFFN) fun = Layer.Function.DIFF; } if (layerForFunction.get(fun) == null) layerForFunction.put(fun, layer); } } /** * Method to log errors during node extraction. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -