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

📄 ercantenna.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ERCAntenna.java * * Copyright (c) 2004 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.erc;import com.sun.electric.database.geometry.DBMath;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.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;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.Connection;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.database.variable.VarContext;import com.sun.electric.technology.ArcProto;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.user.ErrorLogger;import java.awt.geom.AffineTransform;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;/** * This is the Antenna checker of the Electrical Rule Checker tool. * <P> * Antenna rules are required by some IC manufacturers to ensure that the transistors of the * chip are not destroyed during fabrication.  This is because, during fabrication, the wafer is * bombarded with ions while making the polysilicon and metal layers. * These ions must find a path to through the wafer (to the substrate and active layers at the bottom). * If there is a large area of poly or metal, and if it connects ONLY to gates of transistors * (not to source or drain or any other active material) then these ions will travel through * the transistors.  If the ratio of the poly or metal "sidewall area" to the transistor gate area * is too large, the transistors will be destroyed.  The "sidewall area" is the area of the sides * of the poly or metal wires, so it is the perimeter times the thickness. *<P> * Things to do: *   Have errors show the gates; *   Not all active connections excuse the area trouble...they should be part of the ratio formula */public class ERCAntenna{	private static class AntennaObject	{		/** the object */							Geometric   geom;		/** the depth of hierarchy at this node */	int         depth;		/** end of arc to walk along */				int         otherend;		/** the hierarchical stack at this node */	NodeInst [] hierstack;		AntennaObject(Geometric geom) { this.geom = geom; }		/**		 * Method to load antenna object "ao" with the hierarchical stack in "stack" that is		 * "depth" deep.		 */		private void loadAntennaObject(NodeInst [] stack, int depth)		{			hierstack = new NodeInst[depth];			for(int i=0; i<depth; i++) hierstack[i] = stack[i];		}	};		/** default maximum ratio of poly to gate area */		public static final double DEFPOLYRATIO  = 200;	/** default maximum ratio of metal to gate area */		public static final double DEFMETALRATIO = 400;	/** default poly thickness for side-area */				public static final double DEFPOLYTHICKNESS  = 2;	/** default metal thickness for side-area */			public static final double DEFMETALTHICKNESS = 5.7;	/** nothing found on the path */						private static final int ERCANTPATHNULL   = 0;	/** found a gate on the path */							private static final int ERCANTPATHGATE   = 1;	/** found active on the path */							private static final int ERCANTPATHACTIVE = 2;	/** search was aborted */								private static final int ERCABORTED       = 3;	/** head of linked list of antenna objects to spread */	private List<AntennaObject>     firstSpreadAntennaObj;	/** current technology being considered */				private Technology              curTech;		/** top-level cell being checked */						private Cell                    topCell;	/** accumulated gate area */							private double                  totalGateArea;	/** the worst ratio found */							private double                  worstRatio;	/** A list of AntennaObjects to process. */				private List<AntennaObject>     pathList;	/** Map from ArcProtos to Layers. */					private HashMap<ArcProto,Layer> arcProtoToLayer;	/** Map from Layers to ArcProtos. */					private HashMap<Layer,ArcProto> layerToArcProto;	/** Map for marking ArcInsts and NodeInsts. */			private HashSet<Geometric>      fsGeom;	/** Map for marking Cells. */							private HashSet<Cell>           fsCell;    /** for storing errors */                               private ErrorLogger             errorLogger;	/************************ CONTROL ***********************/	private ERCAntenna() {}	/**	 * The main entrypoint for Antenna checking.	 * Creating an ERCAntenna object checks the current cell.	 */	public static void doAntennaCheck()	{		UserInterface ui = Job.getUserInterface();		Cell cell = ui.needCurrentCell();		if (cell == null) return;		new AntennaCheckJob(cell);	}	/**	 * Class to do antenna checking in a new thread.	 */	private static class AntennaCheckJob extends Job	{		private Cell cell;        private AntennaCheckJob(Cell cell)		{			super("ERC Antenna Check", ERC.tool, Job.Type.EXAMINE, null, null, Job.Priority.USER);			this.cell = cell;			startJob();		}		public boolean doIt() throws JobException		{			ERCAntenna handler = new ERCAntenna();			handler.topCell = cell;			handler.doCheck(this);			return true;		}	}	/**	 * Method to do the Antenna check.	 */	private void doCheck(Job job)	{		curTech = topCell.getTechnology();		// maps for marking nodes and arcs, and also for marking cells		fsGeom = new HashSet<Geometric>();		fsCell = new HashSet<Cell>();		// create mappings between ArcProtos and Layers		arcProtoToLayer = new HashMap<ArcProto,Layer>();		layerToArcProto = new HashMap<Layer,ArcProto>();		for(Iterator<ArcProto> it = curTech.getArcs(); it.hasNext(); )		{			ArcProto ap = it.next();			ArcProto.Function aFun = ap.getFunction();			if (!aFun.isMetal() && aFun != ArcProto.Function.POLY1) continue;			for(Iterator<Layer> lIt = curTech.getLayers(); lIt.hasNext(); )			{				Layer lay = lIt.next();				Layer.Function lFun = lay.getFunction();				if ((aFun.isMetal() && lFun.isMetal() && aFun.getLevel() == lFun.getLevel()) ||					(aFun.isPoly() && lFun.isPoly() && aFun.getLevel() == lFun.getLevel()))				{					arcProtoToLayer.put(ap, lay);					layerToArcProto.put(lay, ap);					break;				}			}		}		// initialize error logging		long startTime = System.currentTimeMillis();		errorLogger = ErrorLogger.newInstance("ERC Antella Rules Check");		// now check each layer of the cell		int lasterrorcount = 0;		worstRatio = 0;		for(Layer lay : layerToArcProto.keySet())		{			System.out.println("Checking Antenna rules for " + lay.getName() + "...");			// clear timestamps on all cells			fsCell.clear();			// do the check for this level			if (checkThisCell(topCell, lay, job)) break;			int i = errorLogger.getNumErrors();			if (i != lasterrorcount)			{				System.out.println("  Found " + (i - lasterrorcount) + " errors");				lasterrorcount = i;			}		}		long endTime = System.currentTimeMillis();		int errorCount = errorLogger.getNumErrors();		if (errorCount == 0)		{			System.out.println("No antenna errors found (took " + TextUtils.getElapsedTime(endTime - startTime) + ")");		} else		{			System.out.println("FOUND " + errorCount + " ANTENNA ERRORS (took " + TextUtils.getElapsedTime(endTime - startTime) + ")");		}		errorLogger.termLogging(true);		fsGeom = null;		fsCell = null;	}	/**	 * Method to check the contents of a cell.	 * @param cell the Cell to check.	 * @param lay the Layer to check in the Cell.	 * @return true if aborted	 */	private boolean checkThisCell(Cell cell, Layer lay, Job job)	{		// examine every node and follow all relevant arcs		fsGeom.clear();		for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )		{			if (job.checkAbort()) return true;			NodeInst ni = it.next();			if (fsGeom.contains(ni)) continue;			fsGeom.add(ni);			// check every connection on the node			for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); )			{				PortInst pi = pIt.next();				// ignore if an arc on this port is already seen				boolean seen = false;				for(Iterator<Connection> cIt = pi.getConnections(); cIt.hasNext(); )				{					Connection con = cIt.next();					ArcInst ai = con.getArc();					if (fsGeom.contains(ai)) { seen = true;   break; }				}//				for(Iterator cIt = ni.getConnections(); cIt.hasNext(); )//				{//					Connection con = cIt.next();//					ArcInst ai = con.getArc();//					if (con.getPortInst() == pi && fsGeom.contains(ai)) { seen = true;   break; }//				}				if (seen) continue;				totalGateArea = 0.0;				pathList = new ArrayList<AntennaObject>();				int found = followNode(ni, pi.getPortProto(), lay, DBMath.MATID, job);				if (found == ERCABORTED) return true;				if (found == ERCANTPATHGATE)				{					// gather the geometry here					PolyMerge vmerge = null;					for(AntennaObject ao : pathList)					{						if (ao.geom instanceof NodeInst)						{							NodeInst oni = (NodeInst)ao.geom;							AffineTransform trans = oni.rotateOut();							for(int i = ao.depth-1; i >= 0; i--)							{								AffineTransform tTrans = ao.hierstack[i].translateOut();								trans.concatenate(tTrans);								AffineTransform rTrans = ao.hierstack[i].rotateOut();								trans.concatenate(rTrans);							}							Technology tech = oni.getProto().getTechnology();							if (tech != curTech) continue;							Poly [] polyList = tech.getShapeOfNode(oni);							for(int i=0; i<polyList.length; i++)							{								Poly poly = polyList[i];								if (poly.getLayer() != lay) continue;								if (vmerge == null)									vmerge = new PolyMerge();								poly.transform(trans);								vmerge.addPolygon(poly.getLayer(), poly);							}						} else						{							ArcInst ai = (ArcInst)ao.geom;							AffineTransform trans = new AffineTransform();							for(int i = ao.depth-1; i >= 0; i--)							{								AffineTransform tTrans = ao.hierstack[i].translateOut();

⌨️ 快捷键说明

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