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

📄 lef.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: LEF.java * Input/output tool: LEF (Library Exchange Format) reader * Written by Steven M. Rubin, Sun Microsystems. * * 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.io.input;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;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.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.technologies.Generic;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** * This class reads files in LEF files. * <BR> * Note that this reader was built by examining LEF files and reverse-engineering them. * It does not claim to be compliant with the LEF specification, but it also does not * claim to define a new specification.  It is merely incomplete. */public class LEF extends LEFDEF{	/*************** LEF PATHS ***************/	private static class LEFPath	{		private Point2D []  pt;		private NodeInst [] ni;		private double      width;		private ArcProto    arc;		private LEFPath     nextLEFPath;		private LEFPath()		{			pt = new Point2D[2];			ni = new NodeInst[2];		}	}	/**	 * Method to import a library from disk.	 * @param lib the library to fill	 * @return the created library (null on error).	 */	protected Library importALibrary(Library lib)	{		// remove any vias in the globals		firstViaDefFromLEF = null;		widthsFromLEF = new HashMap<ArcProto,Double>();		knownLayers = new HashMap<String,GetLayerInformation>();		initKeywordParsing();		try		{            if (!readFile(lib)) return null; // error during reading        } catch (IOException e)		{			System.out.println("ERROR reading LEF libraries");		}		return lib;	}	/**	 * Helper method for keyword processing which removes comments.	 * @param line a line of text just read.	 * @return the line after comments have been removed. 	 */	protected String preprocessLine(String line)	{		int sharpPos = line.indexOf('#');		if (sharpPos >= 0) return line.substring(0, sharpPos);		return line;	}	/**	 * Method to read the LEF file.	 */	private boolean readFile(Library lib)		throws IOException	{		for(;;)		{			// get the next keyword			String key = getAKeyword();			if (key == null) break;			if (key.equalsIgnoreCase("LAYER"))			{				if (readLayer(lib)) return true;			}			if (key.equalsIgnoreCase("MACRO"))			{				if (readMacro(lib)) return true;			}			if (key.equalsIgnoreCase("VIA"))			{				if (readVia(lib)) return true;			}			if (key.equalsIgnoreCase("VIARULE") || key.equalsIgnoreCase("SITE") ||				key.equalsIgnoreCase("ARRAY"))			{				String name = getAKeyword();				ignoreToEnd(name);				continue;			}			if (key.equalsIgnoreCase("SPACING"))			{				ignoreToEnd(key);				continue;			}			if (key.equalsIgnoreCase("MINFEATURE"))			{				ignoreToSemicolon(key);				continue;			}		}		return false;	}	private boolean readVia(Library lib)		throws IOException	{		// get the via name		String viaName = getAKeyword();		if (viaName == null) return true;		// create a new via definition		ViaDef vd = new ViaDef();		vd.viaName = viaName;		vd.sX = vd.sY = 0;		vd.via = null;		vd.lay1 = vd.lay2 = null;		vd.nextViaDef = firstViaDefFromLEF;		firstViaDefFromLEF = vd;		boolean ignoreDefault = true;		for(;;)		{			// get the next keyword			String key = getAKeyword();			if (key == null) return true;			if (ignoreDefault)			{				ignoreDefault = false;				if (key.equalsIgnoreCase("DEFAULT")) continue;			}			if (key.equalsIgnoreCase("END"))			{				key = getAKeyword();				break;			}			if (key.equalsIgnoreCase("RESISTANCE"))			{				if (ignoreToSemicolon(key)) return true;				continue;			}			if (key.equalsIgnoreCase("LAYER"))			{				key = getAKeyword();				if (key == null) return true;				GetLayerInformation li = getLayerInformation(key);				if (li.arc != null)				{					if (vd.lay1 == null) vd.lay1 = li.arc; else						vd.lay2 = li.arc;				}				if (ignoreToSemicolon("LAYER")) return true;				continue;			}			if (key.equalsIgnoreCase("RECT"))			{				// handle definition of a via rectangle				key = getAKeyword();				if (key == null) return true;				double lX = convertLEFString(key);				key = getAKeyword();				if (key == null) return true;				double lY = convertLEFString(key);				key = getAKeyword();				if (key == null) return true;				double hX = convertLEFString(key);				key = getAKeyword();				if (key == null) return true;				double hY = convertLEFString(key);				// accumulate largest layer size				if (hX-lX > vd.sX) vd.sX = hX - lX;				if (hY-lY > vd.sY) vd.sY = hY - lY;				if (ignoreToSemicolon("RECT")) return true;				continue;			}		}		if (vd.lay1 != null && vd.lay2 != null)		{			for(Iterator<PrimitiveNode> it = Technology.getCurrent().getNodes(); it.hasNext(); )			{				PrimitiveNode np = it.next();				if (np.getFunction() != PrimitiveNode.Function.CONTACT) continue;				PortProto pp = np.getPort(0);				if (pp.connectsTo(vd.lay1) && pp.connectsTo(vd.lay2))				{					vd.via = np;					break;				}			}		}		return false;	}	private boolean readMacro(Library lib)		throws IOException	{		String cellName = getAKeyword();		if (cellName == null)		{			System.out.println("EOF parsing MACRO header");			return true;		}		cellName = cellName + "{lay.sk}";		Cell cell = Cell.makeInstance(lib, cellName);		if (cell == null)		{			System.out.println("Cannot create cell '" + cellName + "'");			return true;		}		for(;;)		{			// get the next keyword			String key = getAKeyword();			if (key == null)			{				System.out.println("EOF parsing MACRO");				return true;			}			if (key.equalsIgnoreCase("END"))			{				key = getAKeyword();				break;			}			if (key.equalsIgnoreCase("SOURCE") || key.equalsIgnoreCase("FOREIGN") ||				key.equalsIgnoreCase("SYMMETRY") || key.equalsIgnoreCase("SITE") ||				key.equalsIgnoreCase("CLASS") || key.equalsIgnoreCase("LEQ") ||				key.equalsIgnoreCase("POWER"))			{				if (ignoreToSemicolon(key)) return true;				continue;			}			if (key.equalsIgnoreCase("ORIGIN"))			{				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading ORIGIN X");					return true;				}				double oX = convertLEFString(key);				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading ORIGIN Y");					return true;				}				double oY = convertLEFString(key);				if (ignoreToSemicolon("ORIGIN")) return true;				// create or move the cell-center node				NodeInst ccNi = null;				for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )				{					NodeInst ni = it.next();					if (ni.getProto() == Generic.tech().cellCenterNode) { ccNi = ni;   break; }				}				if (ccNi == null)				{					double sX = Generic.tech().cellCenterNode.getDefWidth();					double sY = Generic.tech().cellCenterNode.getDefHeight();					ccNi = NodeInst.makeInstance(Generic.tech().cellCenterNode, new Point2D.Double(oX, oY), sX, sY, cell);					if (ccNi == null)					{						System.out.println("Line " + lineReader.getLineNumber() + ": Cannot create cell center node");						return true;					}					ccNi.setHardSelect();					ccNi.setVisInside();				} else				{					double dX = oX - ccNi.getTrueCenterX();					double dY = oY - ccNi.getTrueCenterY();					ccNi.move(dX, dY);				}				continue;			}			if (key.equalsIgnoreCase("SIZE"))			{				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading SIZE X");					return true;				}				double wid = convertLEFString(key);		// get width				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading SIZE 'BY'");					return true;				}				if (!key.equalsIgnoreCase("BY"))				{					System.out.println("Line " + lineReader.getLineNumber() + ": Expected 'by' in SIZE");					return true;				}				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading SIZE Y");					return true;				}				double hei = convertLEFString(key);		// get height				cell.newVar(prXkey, new Double(wid));				cell.newVar(prYkey, new Double(hei));				if (ignoreToSemicolon("SIZE")) return true;				if (!PLACELEFGEOMETRY)				{					Point2D ctr = new Point2D.Double(wid/2, hei/2);					NodeInst.makeInstance(Generic.tech().invisiblePinNode, ctr, wid, hei, cell);				}				continue;			}			if (key.equalsIgnoreCase("PIN"))			{				if (readPin(cell)) return true;				continue;			}			if (key.equalsIgnoreCase("OBS"))			{				if (readObs(cell)) return true;				continue;			}			System.out.println("Line " + lineReader.getLineNumber() + ": Unknown MACRO keyword (" + key + ")");			return true;		}		return false;	}	private boolean readObs(Cell cell)		throws IOException	{		NodeProto np = null;		for(;;)		{			String key = getAKeyword();			if (key == null)			{				System.out.println("EOF parsing OBS");				return true;			}			if (key.equalsIgnoreCase("END")) break;			if (key.equalsIgnoreCase("LAYER"))			{				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading LAYER clause");					return true;				}				GetLayerInformation li = getLayerInformation(key);				np = li.pure;				if (li.layerFun == Layer.Function.UNKNOWN || np == null)				{					System.out.println("Line " + lineReader.getLineNumber() + ": Unknown layer name (" + key + ")");					return true;				}				if (ignoreToSemicolon("LAYER")) return true;				continue;			}			if (key.equalsIgnoreCase("RECT"))			{				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading RECT low X");					return true;				}				double lX = convertLEFString(key);				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading RECT low Y");					return true;				}				double lY = convertLEFString(key);				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading RECT high X");					return true;				}				double hX = convertLEFString(key);				key = getAKeyword();				if (key == null)				{					System.out.println("EOF reading RECT high Y");					return true;				}				double hY = convertLEFString(key);				if (ignoreToSemicolon("RECT")) return true;				// make the obstruction				if (PLACELEFGEOMETRY)				{					if (np == null)					{						System.out.println("Line " + lineReader.getLineNumber() + ": No layers for RECT");						return true;					}					Point2D ctr = new Point2D.Double((lX+hX)/2, (lY+hY)/2);					double sX = Math.abs(hX - lX);					double sY = Math.abs(hY - lY);					NodeInst ni = NodeInst.makeInstance(np, ctr, sX, sY, cell);					if (ni == null)					{						System.out.println("Line " + lineReader.getLineNumber() + ": Cannot create node for RECT");						return true;					}				}				continue;			}		}		return false;	}	private boolean readPin(Cell cell)		throws IOException	{		// get the pin name		String key = getAKeyword();		if (key == null)		{			System.out.println("EOF parsing PIN name");			return true;		}		String pinName = key.replace('<', '[').replace('>', ']');		PortCharacteristic useCharacteristics = PortCharacteristic.UNKNOWN;		PortCharacteristic portCharacteristics = PortCharacteristic.UNKNOWN;		for(;;)		{			key = getAKeyword();			if (key == null)			{				System.out.println("EOF parsing PIN");				return true;			}			if (key.equalsIgnoreCase("END"))			{				key = getAKeyword();				break;			}

⌨️ 快捷键说明

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