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

📄 def.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: DEF.java * Input/output tool: DEF (Design 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.Orientation;import com.sun.electric.database.geometry.Poly;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.hierarchy.View;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.CellName;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.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.io.IOTool;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.io.IOException;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * This class reads files in DEF files. * <BR> * Note that this reader was built by examining DEF files and reverse-engineering them. * It does not claim to be compliant with the DEF specification, but it also does not * claim to define a new specification.  It is merely incomplete. * * R. Reese (RBR) - modified Spring 2007 to be able to import a DEF file to a currently * opened View. The intended use is for the Views to either be layout or schematic. * If the view is layout, then all geometry is input and unrouted net connections * are used to maintain connectivity between logical nets and physical geometries. * At some point in the future, these unrouted nets need to be cleaned up, but for * now, the use of unrouted nets allows the layout to pass DRC and to be simulated. * Can also import to a schematic view - this creates a hodgepodge of icons in the * schematic view but net connections are correct so NCC can be used to check * layout vs schematic. This is useful in a hierarchical design where part of the * design is imported DEF (say, a standard cell layout), and the rest of the design * is manual layout. Having a schematic view for the imported DEF allows NCC to * complain less when checking the design. */public class DEF extends LEFDEF{	private double  scaleUnits;	private ViaDef  firstViaDef;	private Hashtable<String,PortInst> specialNetsHT = null;	private Hashtable<String,PortInst> normalNetsHT = null;	private Hashtable<Double,List<NodeInst>> PortHT = null;	private boolean schImport = false;	private Pattern pat_starleftbracket = Pattern.compile(".*\\\\"+ "\\[");	private Pattern pat_leftbracket = Pattern.compile("\\\\"+ "\\[");	private Pattern pat_starrightbracket = Pattern.compile(".*\\\\"+ "\\]");	private Pattern pat_rightbracket = Pattern.compile("\\\\"+ "\\]");	/**	 * 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)	{		initKeywordParsing();		scaleUnits = 1000;		firstViaDef = null;		// read the file		try		{			if (!readFile(lib)) return null; // error during reading        } catch (IOException e)		{			System.out.println("ERROR reading DEF libraries");		}		return lib;	}	private boolean ignoreToSemicolon(String command)		throws IOException	{		// ignore up to the next semicolon		for(;;)		{			String key = mustGetKeyword(command);			if (key == null) return true;			if (key.equals(";")) break;		}		return false;	}	private String mustGetKeyword(String where)		throws IOException	{		String key = getAKeyword();		if (key == null) reportError("EOF parsing " + where);		return key;	}	private double convertDEFString(String key)	{		double v = TextUtils.atof(key) / scaleUnits;		return TextUtils.convertFromDistance(v, Technology.getCurrent(), TextUtils.UnitScale.MICRO);	}	private void reportError(String command)	{		System.out.println("File " + filePath + ", line " + lineReader.getLineNumber() + ": " + command);	}	/**	 * Method to read the DEF file.	 */	private boolean readFile(Library lib)		throws IOException	{		Cell cell = null;		for(;;)		{			// get the next keyword			String key = getAKeyword();			if (key == null) break;			if (key.equalsIgnoreCase("VERSION") || key.equalsIgnoreCase("NAMESCASESENSITIVE") ||				key.equalsIgnoreCase("DIVIDERCHAR") || key.equalsIgnoreCase("BUSBITCHARS") ||				key.equalsIgnoreCase("DIEAREA") || key.equalsIgnoreCase("ROW") ||				key.equalsIgnoreCase("TRACKS") || key.equalsIgnoreCase("GCELLGRID") ||				key.equalsIgnoreCase("HISTORY") || key.equalsIgnoreCase("TECHNOLOGY"))			{				if (ignoreToSemicolon(key)) return true;				continue;			}			if (key.equalsIgnoreCase("DEFAULTCAP") || key.equalsIgnoreCase("REGIONS"))			{				if (ignoreBlock(key)) return true;				continue;			}			if (key.equalsIgnoreCase("DESIGN"))			{				String cellName = mustGetKeyword("DESIGN");				if (cellName == null) return true;				/* RBR - first, see if Cell name is equal to current cells				 * it exists then read into cell				 */				cell = lib.getCurCell();				if (Input.isNewLibraryCreated()== false)				{					// reading into current cell, current library					if (cell == null)					{						reportError("A cell must be currently opened for this operation, aborting.");						return true;					}					if (!cell.getCellName().getName().equals(cellName))					{						reportError("Cell name in DEF file '" + cellName + "' does not equal current cell name '" + cell.getCellName().getName() + "', aborting.");						return true;					}					View cellView = cell.getCellName().getView();					if (cellView.getAbbreviation().equals("sch"))					{						schImport = true; // special flag when importing into schematic view					}				}				else if (cell == null || !cell.getCellName().getName().equals(cellName))				{					// does not equal current cell, so lets					cell = Cell.makeInstance(lib, cellName);				}				if (cell == null)				{					reportError("Cannot create cell '" + cellName + "'");					return true;				}				if (ignoreToSemicolon("DESIGN")) return true;				continue;			}			if (key.equalsIgnoreCase("UNITS"))			{				if (readUnits()) return true;				continue;			}			if (key.equalsIgnoreCase("PROPERTYDEFINITIONS"))			{				if (readPropertyDefinitions()) return true;				continue;			}			if (key.equalsIgnoreCase("VIAS"))			{				if (readVias(cell)) return true;				continue;			}			if (key.equalsIgnoreCase("COMPONENTS"))			{				if (readComponents(cell)) return true;				continue;			}			if (key.equalsIgnoreCase("PINS"))			{				if (readPins(cell)) return true;				continue;			}			if (key.equalsIgnoreCase("SPECIALNETS"))			{				if (readNets(cell, true)) return true;				continue;			}			if (key.equalsIgnoreCase("NETS"))			{				if (readNets(cell, false)) return true;				continue;			}			if (key.equalsIgnoreCase("END"))			{				key = getAKeyword();				break;			}		}		return false;	}	private boolean ignoreBlock(String command)		throws IOException	{		for(;;)		{			// get the next keyword			String key = mustGetKeyword(command);			if (key == null) return true;			if (key.equalsIgnoreCase("END"))			{				getAKeyword();				break;			}		}		return false;	}	private Point2D readCoordinate()		throws IOException	{		// get "("		String key = mustGetKeyword("coordinate");		if (key == null) return null;		if (!key.equals("("))		{			reportError("Expected '(' in coordinate");			return null;		}		// get X		key = mustGetKeyword("coordinate");		if (key == null) return null;		double x = convertDEFString(key);		// get Y		key = mustGetKeyword("coordinate");		if (key == null) return null;		double y = convertDEFString(key);		// get ")"		key = mustGetKeyword("coordinate");		if (key == null) return null;		if (!key.equals(")"))		{			reportError("Expected ')' in coordinate");			return null;		}		return new Point2D.Double(x, y);	}	/**	 * Find nodeProto with same view as the parent cell	 */	private Cell getNodeProto(String name, Library curlib, Cell parent)	{		// first see if this cell is in the current library		CellName cn;		if (schImport)		{			cn = CellName.newName(name,View.ICON,0);		} else		{			cn = CellName.newName(name,parent.getView(),0);		}		Cell cell = curlib.findNodeProto(cn.toString());		if (cell != null) return cell;		// now look in other libraries		for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); )		{			Library lib = it.next();			if (lib.isHidden()) continue;			if (lib == curlib) continue;			cell = lib.findNodeProto(name);			if (cell != null)			{				// must copy the cell//				Cell newCell = copyrecursively(cell, cell->protoname, curlib, cell->cellview,//					FALSE, FALSE, "", FALSE, FALSE, TRUE, new HashSet());//				return newCell;				return cell;			}		}		return null;	}	private Cell getNodeProto(String name, Library curlib)	{		// first see if this cell is in the current library		Cell cell = curlib.findNodeProto(name);		if (cell != null) return cell;		// now look in other libraries		for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); )		{			Library lib = it.next();			if (lib.isHidden()) continue;			if (lib == curlib) continue;			cell = lib.findNodeProto(name);			if (cell != null)			{				// must copy the cell//				Cell newCell = copyrecursively(cell, cell->protoname, curlib, cell->cellview,//					FALSE, FALSE, "", FALSE, FALSE, TRUE, new HashSet());//				return newCell;				return cell;			}		}		return null;	}	//RBR - temp method until I figure out	//why in Java 6.0 my use of GetOrientation	//generates a compile error	private Orientation FetchOrientation() throws IOException	{		String key = mustGetKeyword("orientation");		if (key == null) return null;		int angle;		boolean transpose = false;		if (key.equalsIgnoreCase("N"))  { angle = 0;    } else		if (key.equalsIgnoreCase("S"))  { angle = 1800; } else		if (key.equalsIgnoreCase("E"))  { angle = 2700; } else		if (key.equalsIgnoreCase("W"))  { angle = 900;  } else		if (key.equalsIgnoreCase("FN")) { angle = 900;   transpose = true; } else		if (key.equalsIgnoreCase("FS")) { angle = 2700;  transpose = true; } else		if (key.equalsIgnoreCase("FE")) { angle = 1800;  transpose = true; } else		if (key.equalsIgnoreCase("FW")) { angle = 0;     transpose = true; } else		{			reportError("Unknown orientation (" + key + ")");			return null;		}		return (Orientation.fromC(angle, transpose));	}	private class GetOrientation	{		private Orientation orient;		private GetOrientation()			throws IOException		{			String key = mustGetKeyword("orientation");			if (key == null) return;			int angle;			boolean transpose = false;			if (key.equalsIgnoreCase("N")) { angle = 0; } else			if (key.equalsIgnoreCase("S")) { angle = 1800; } else			if (key.equalsIgnoreCase("E")) { angle = 2700; } else			if (key.equalsIgnoreCase("W")) { angle = 900; } else			if (key.equalsIgnoreCase("FN")) { angle = 900;  transpose = true; } else			if (key.equalsIgnoreCase("FS")) { angle = 2700; transpose = true; } else			if (key.equalsIgnoreCase("FE")) { angle = 1800; transpose = true; } else			if (key.equalsIgnoreCase("FW")) { angle = 0;    transpose = true; } else			{				reportError("Unknown orientation (" + key + ")");				return;			}			orient = Orientation.fromC(angle, transpose);		}	}	/**	 * Method to look for a connection to arcs of type "ap" in cell "cell"	 * at (x, y).  The connection can not be on "not" (if it is not null).	 * If found, return the PortInst.	 *	 * This function became too slow as the number of nets in cell increased.	 * Replaced by function below. RBR Mar 2007	 *///	private PortInst findConnection(double x, double y, ArcProto ap, Cell cell, NodeInst noti)//	{//		Rectangle2D bound = new Rectangle2D.Double(x, y, 0, 0);//		Point2D pt = new Point2D.Double(x, y);//		for(Iterator<RTBounds> sea = cell.searchIterator(bound); sea.hasNext(); )//		{//			RTBounds geom = sea.next();//			if (!(geom instanceof NodeInst)) continue;//			NodeInst ni = (NodeInst)geom;//			if (ni == noti) continue;//			for(Iterator<PortInst> it = ni.getPortInsts(); it.hasNext(); )//			{//				PortInst pi = (PortInst)it.next();//				if (!pi.getPortProto().connectsTo(ap)) continue;//				Poly poly = pi.getPoly();//				if (poly.isInside(pt)) return pi;//			}//		}//		return null;//	}	private PortInst findConnection(double x, double y, ArcProto ap, Cell cell, NodeInst noti)	{		if (PortHT.containsKey(x+y)) {			List<NodeInst> pl = PortHT.get(x+y);			Point2D pt = new Point2D.Double(x, y);			for (int i=0; i < pl.size(); i++)			{				NodeInst ni = pl.get(i);				if (ni == noti) continue;				for(Iterator<PortInst> it = ni.getPortInsts(); it.hasNext(); )				{					PortInst pi = it.next();					if (!pi.getPortProto().connectsTo(ap)) continue;					Poly poly = pi.getPoly();					if (poly.isInside(pt)) return pi;				}			}		}		return null;	}	/**	 * Method to look for a connection to arcs of type "ap" in cell "cell"	 * at (x, y).  If nothing is found, create a pin.  In any case, return	 * the PortInst.  Returns null on error.	 */	private PortInst getPin(double x, double y, ArcProto ap, Cell cell)	{		// if there is an existing connection, return it		PortInst pi = findConnection(x, y, ap, cell, null);		if (pi != null) return pi;		// nothing found at this location: create a pin		NodeProto pin = ap.findPinProto();		double sX = pin.getDefWidth();		double sY = pin.getDefHeight();		NodeInst ni = NodeInst.makeInstance(pin, new Point2D.Double(x, y), sX, sY, cell);		if (ni == null)		{			reportError("Unable to create net pin");			return null;		}		List<NodeInst> pl;		if (PortHT.containsKey(x+y))		{			pl = PortHT.get(x+y);		} else		{			pl = new ArrayList<NodeInst>();			PortHT.put(x+y, pl);		}		pl.add(ni);		return ni.getOnlyPortInst();	}	/*************** PINS ***************/	private boolean readPins(Cell cell)		throws IOException	{		if (ignoreToSemicolon("PINS")) return true;		for(;;)		{			// get the next keyword			String key = mustGetKeyword("PINs");			if (key == null) return true;			if (key.equals("-"))			{				if (readPin(cell)) return true;				continue;			}			if (key.equalsIgnoreCase("END"))			{				key = getAKeyword();				break;			}			// ignore the keyword			if (ignoreToSemicolon(key)) return true;		}		return false;	}	private String translateDefName (String name)	{		Matcher m_starleftbracket = pat_starleftbracket.matcher(name);		Matcher m_starrightbracket = pat_starrightbracket.matcher(name);		if ( m_starleftbracket.matches() || m_starrightbracket.matches())		{			String tmpa, tmpb;			Matcher m_leftbracket = pat_leftbracket.matcher(name);			tmpa = m_leftbracket.replaceAll("[");			Matcher m_rightbracket = pat_rightbracket.matcher(tmpa);			tmpb = m_rightbracket.replaceAll("]");

⌨️ 快捷键说明

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