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

📄 getnetlist.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: GetNetlist.java * Silicon compiler tool (QUISC): read a netlist * Written by Andrew R. Kostiuk, Queen's University. * Translated to Java 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.sc;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.TextUtils;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * This is the netlist reader of the Silicon Compiler tool. */public class GetNetlist{	/***********************************************************************		General Constants	------------------------------------------------------------------------*/	private static final int GND = 0;	private static final int PWR = 1;	/***** Directions that ports can be attached to *****/	/** mask for port direction */		public static final int PORTDIRMASK	= 0x0000000F;	/** port direction up */			public static final int PORTDIRUP	= 0x00000001;	/** port direction down */			public static final int PORTDIRDOWN	= 0x00000002;	/** port direction right */			public static final int PORTDIRRIGHT= 0x00000004;	/** port direction left */			public static final int PORTDIRLEFT	= 0x00000008;	/** port type mask */				public static final int PORTTYPE	= 0x000003F0;	/** ground port */					public static final int GNDPORT		= 0x00000010;	/** power port */					public static final int PWRPORT		= 0x00000020;	/** bidirectional port */			public static final int BIDIRPORT	= 0x00000040;	/** output port */					public static final int OUTPORT		= 0x00000080;	/** input port */					public static final int INPORT		= 0x00000100;	/** unknown port */					public static final int UNPORT		= 0x00000200;	/***********************************************************************		QUISC Cell Structure	------------------------------------------------------------------------*/	static class SCCell	{		/** name of complex cell */				String    		name;		/** maximum number of nodes */			int       		maxNodeNum;		/** list of instances for cell */		List<SCNiTree>	niList;		/** extracted nodes */					ExtNode 		exNodes;		/** flags for processing cell */		int       		bits;		/** list of power ports */				ExtNode 		power;		/** list of ground ports */				ExtNode 		ground;		/** list of ports */					SCPort    		ports, lastPort;		/** placement information of cell */	Place.SCPlace   placement;		/** routing information for cell */		Route.SCRoute   route;		/** next in list of SC cells */			SCCell    		next;	};	static class SCPort	{		/** name of port */						String   name;		/** special node */						SCNiTree node;		/** cell on which this port resides */	SCCell   parent;		/** port attributes */					int      bits;		/** pointer to next port */				SCPort   next;	};	static class SCCellNums	{		/** active area from top */				int		topActive;		/** active are from bottom */			int		bottomActive;		/** active area from left */			int		leftActive;		/** active are from right */			int		rightActive;	};	/***********************************************************************		Instance Tree Structure	------------------------------------------------------------------------*/	/***** Types of Instances *****/	public static final int LEAFCELL     = 0;	public static final int COMPLEXCELL  = 1;	public static final int SPECIALCELL  = 2;	public static final int FEEDCELL     = 3;	public static final int STITCH       = 4;	public static final int LATERALFEED  = 5;	static class SCNiTree	{		/** name of instance */					String		name;		/** alternative number of node */		int			number;		/** type of instance */					int			type;		/** leaf cell or SCCell if complex */	Object		np;		/** x size if leaf cell */				double		size;		/** pointer to connection list */		ConList		connect;		/** list of io ports and ext nodes */	SCNiPort	ports;		/** list of actual power ports */		SCNiPort	power;		/** list of actual ground ports */		SCNiPort	ground;		/** bits for silicon compiler */		int			flags;		/** generic temporary pointer */		Object		tp;		/**		 * Method to create a new instance with a given name and type.		 * @param name name of the instance.		 * @param type type of the instance.		 */		SCNiTree(String name, int type)		{			this.name = name;			this.type = type;			this.number = 0;			this.np = null;			this.size = 0;			this.connect = null;			this.ports = null;			this.power = null;			this.ground = null;			this.flags = 0;			this.tp = null;		}	};	static class SCNiPort	{		/** leaf port or SCPort if on cell */	Object		port;		/** extracted node */					ExtNode		extNode;		/** bits for processing */				int			bits;		/** x position if leaf port */			double		xPos;		/** list of instance ports */			SCNiPort	next;		SCNiPort() {}		SCNiPort(SCNiTree instance)		{			this.port = null;			this.extNode = null;			this.bits = 0;			this.xPos = 0;			this.next = instance.ports;			instance.ports = this;		}	};	/***********************************************************************		Connection Structures	------------------------------------------------------------------------*/	private static class ConList	{		/** pointer to port on node A */		SCNiPort	portA;		/** pointer to node B */				SCNiTree	nodeB;		/** pointer to port on node B */		SCNiPort	portB;		/** pointer to extracted node */		ExtNode		extNode;		/** pointer to next list element */		ConList   	next;	};	/***********************************************************************		Extraction Structures	------------------------------------------------------------------------*/	private static class ExtPort	{		/** instance of extracted node */		SCNiTree	node;		/** instance port */					SCNiPort	port;		/** next in list of common node */		ExtPort		next;	};	/**	 * Class for communicating netlist information to the placer and router.	 */	public static class ExtNode	{		/** optional name of port */			String		name;		/** link list of ports */				ExtPort		firstPort;		/** flags for processing */				int			flags;		/** generic pointer for processing */	Object		ptr;		/** link list of nodes */				ExtNode		next;	};	SCCell	scCells, curSCCell;	/**	 * Read the netlist associated with the current cell.	 * @return true on error.	 */	public boolean readNetCurCell(Cell cell)	{		scCells = null;		curSCCell = null;		if (cell.getView() != View.NETLISTQUISC)		{			System.out.println("Current cell must have QUISC Netlist view");			return true;		}		String [] strings = cell.getTextViewContents();		if (strings == null)		{			System.out.println("Cell " + cell.describe(true) + " has no text in it");			return true;		}		// read entire netlist		boolean errors = false;		for(int i=0; i<strings.length; i++)		{			String inBuf = strings[i].trim();			// check for a comment line or empty line			if (inBuf.length() == 0 || inBuf.charAt(0) == '!') continue;			// break into keywords			List<String> parameters = new ArrayList<String>();			for(int sPtr = 0; sPtr < inBuf.length(); sPtr++)			{				// get rid of leading white space				while (sPtr < inBuf.length() && (inBuf.charAt(sPtr) == ' ' || inBuf.charAt(sPtr) == '\t')) sPtr++;				if (sPtr >= inBuf.length()) break;				// check for string				if (inBuf.charAt(sPtr) == '"')				{					sPtr++;					int endQuote = inBuf.indexOf('"', sPtr);					if (endQuote < 0)					{						System.out.println("ERROR line " + (i+1) + ": Unbalanced quotes ");						errors = true;						break;					}					parameters.add(inBuf.substring(sPtr, endQuote));					sPtr = endQuote;				} else				{					int endSpace = inBuf.indexOf(' ', sPtr);					int endTab = inBuf.indexOf('\t', sPtr);					if (endSpace < 0) endSpace = endTab;					if (endSpace < 0) endSpace = inBuf.length();					if (endTab >= 0 && endTab < endSpace) endSpace = endTab;					parameters.add(inBuf.substring(sPtr, endSpace));					sPtr = endSpace;				}			}			String err = parse(parameters);			if (err != null)			{				System.out.println("ERROR line " + (i+1) + ": " + err);				System.out.println("      Line: " + inBuf);				errors = true;				break;			}		}		// do the "pull" (extract)		String err = pull();		if (err != null)		{			System.out.println(err);			errors = true;		}		return errors;	}	/**	 * Main parsing routine for the Silicon Compiler.	 */	private String parse(List<String> keywords)	{		if (keywords.size() == 0) return null;		String mainKeyword = keywords.get(0);		if (mainKeyword.equalsIgnoreCase("connect")) return connect(keywords);		if (mainKeyword.equalsIgnoreCase("create")) return create(keywords);		if (mainKeyword.equalsIgnoreCase("export")) return export(keywords);		if (mainKeyword.equalsIgnoreCase("extract")) return extract(keywords);		if (mainKeyword.equalsIgnoreCase("set")) return xSet(keywords);		return "Unknown keyword: " + mainKeyword;	}	/**************************************** NETLIST READING: THE CREATE KEYWORD ****************************************/	private String create(List<String> keywords)	{		if (keywords.size() <= 1) return "No keyword for CREATE command";		String sPtr = keywords.get(1);		if (sPtr.equalsIgnoreCase("cell"))		{			if (keywords.size() <= 2) return "No name for CREATE CELL command";			sPtr = keywords.get(2);			// check if cell already exists in cell list			for(SCCell cell = scCells; cell != null; cell = cell.next)			{				if (sPtr.equalsIgnoreCase(cell.name))					return "Cell '" + sPtr + "' already exists in current library";			}			// generate warning message if a leaf cell of the same name exists			if (findLeafCell(sPtr) != null)				System.out.println("WARNING - cell " + sPtr + " may be overridden by created cell");			// create new cell			SCCell newCell = new SCCell();			newCell.name = sPtr;			newCell.maxNodeNum = 0;			newCell.niList = new ArrayList<SCNiTree>();			newCell.exNodes = null;			newCell.bits = 0;			newCell.power = null;			newCell.ground = null;			newCell.ports = null;			newCell.lastPort = null;			newCell.placement = null;			newCell.route = null;			newCell.next = scCells;			scCells = newCell;			curSCCell = newCell;			// create dummy ground and power nodes			SCNiTree ntp = findNi(curSCCell, "ground");			if (ntp != null) return "Instance 'ground' already exists";			ntp = new SCNiTree("ground", SPECIALCELL);			curSCCell.niList.add(ntp);			new SCNiPort(ntp);			ntp.number = curSCCell.maxNodeNum++;			ntp = findNi(curSCCell, "power");			if (ntp != null) return "Instance 'power' already exists";			ntp = new SCNiTree("power", SPECIALCELL);			curSCCell.niList.add(ntp);			new SCNiPort(ntp);			ntp.number = curSCCell.maxNodeNum++;			return null;		}		if (sPtr.equalsIgnoreCase("instance"))		{			if (keywords.size() <= 2) return "No instance name for CREATE INSTANCE command";			String noden = keywords.get(2);			if (keywords.size() <= 3) return "No type name for CREATE INSTANCE command";			String nodep = keywords.get(3);			// search for cell in cell list			SCCell cell = null;			for(SCCell c = scCells; c != null; c = c.next)			{				if (nodep.equalsIgnoreCase(c.name)) { cell = c;   break; }			}			Object proto = cell;			int type = COMPLEXCELL;			double size = 0;			if (cell == null)			{				// search for leaf cell in library				Cell bc = findLeafCell(nodep);				if (bc == null)					return "There is no '" + nodep + "' in the standard cell library";				proto = bc;				type = LEAFCELL;				size = SilComp.leafCellXSize(bc);			}			// check if currently working in a cell			if (curSCCell == null) return "No cell selected";			// check if instance name already exits			SCNiTree ntp = findNi(curSCCell, noden);			if (ntp != null)				return "Instance '" + noden + "' already exists";			// add instance name to tree			ntp = new SCNiTree(noden, type);			curSCCell.niList.add(ntp);			ntp.number = curSCCell.maxNodeNum++;			ntp.np = proto;			ntp.size = size;			// create ni port list			if (type == COMPLEXCELL)			{				SCNiPort oldNiPort = null;				for (SCPort port = ((SCCell)proto).ports; port != null; port = port.next)				{					SCNiPort niPort = new SCNiPort();					niPort.port = port;					niPort.extNode = null;					niPort.bits = 0;					niPort.xPos = 0;					switch (port.bits & PORTTYPE)					{						case GNDPORT:							niPort.next = ntp.ground;							ntp.ground = niPort;							break;						case PWRPORT:							niPort.next = ntp.power;							ntp.power = niPort;							break;						default:							niPort.next = null;							if (oldNiPort == null)							{								ntp.ports = niPort;							} else							{								oldNiPort.next = niPort;							}							oldNiPort = niPort;							break;					}				}			} else			{				SCNiPort oldNiPort = null;				Cell realCell = (Cell)proto;				for(Iterator<PortProto> it = realCell.getPorts(); it.hasNext(); )				{					Export bp = (Export)it.next();					SCNiPort niPort = new SCNiPort();					niPort.port = bp;					niPort.extNode = null;					niPort.bits = 0;					niPort.xPos = SilComp.leafPortXPos(bp);					switch (getLeafPortType(bp))					{						case GNDPORT:							niPort.next = ntp.ground;							ntp.ground = niPort;							break;						case PWRPORT:							niPort.next = ntp.power;							ntp.power = niPort;							break;						default:							niPort.next = null;							if (oldNiPort == null)							{								ntp.ports = niPort;							} else							{								oldNiPort.next = niPort;							}							oldNiPort = niPort;							break;					}				}			}			return null;		}		return "Unknown CREATE command: " + sPtr;	}	/**	 * Method to find the location in a SCNiTree where the node should be placed.	 * If the pointer does not have a value of null, then the object already exits.	 */	private SCNiTree findNi(SCCell cell, String name)	{		for(SCNiTree nPtr : cell.niList)		{			if (nPtr.name.equalsIgnoreCase(name)) return nPtr;		}		return null;	}	/**************************************** NETLIST READING: THE CONNECT KEYWORD ****************************************/	private String connect(List<String> keywords)	{		if (keywords.size() < 4) return "Not enough parameters for CONNECT command";		// search for the first node		String node0Name = keywords.get(1);		String port0Name = keywords.get(2);		SCNiTree ntpA = findNi(curSCCell, node0Name);		if (ntpA == null) return "Cannot find instance '" + node0Name + "'";		SCNiPort portA = findPp(ntpA, port0Name);		if (portA == null)			return "Cannot find port '" + port0Name + "' on instance '" + node0Name + "'";		// search for the second node		String node1Name = keywords.get(3);		SCNiTree ntpB = findNi(curSCCell, node1Name);		if (ntpB == null) return "Cannot find instance '" + node1Name + "'";		// check for special power or ground node		SCNiPort portB = ntpB.ports;		if (ntpB.type != SPECIALCELL)		{			if (keywords.size() < 5) return "Not enough parameters for CONNECT command";			String port1Name = keywords.get(4);			portB = findPp(ntpB, port1Name);			if (portB == null)				return "Cannot find port '" + port1Name + "' on instance '" + node1Name + "'";		}		conList(ntpA, portA, ntpB, portB);		return null;	}	/**	 * Method to find the port on the given node instance.	 * @return null if port is not found.	 */	private SCNiPort findPp(SCNiTree ntp, String name)	{		SCNiPort port = null;		if (ntp == null) return null;		switch (ntp.type)

⌨️ 快捷键说明

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