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

📄 topology.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: Topology.java * Input/output tool: superclass for output modules that write connectivity. * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2003 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.output;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.HierarchyEnumerator;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.network.Global;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.network.NetworkTool;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.Connection;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.generator.sclibrary.SCLibraryGen;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;/** * This is the Simulation Interface tool. */public abstract class Topology extends Output{	private static final boolean DEBUGTOPOLOGY = false;	/** top-level cell being processed */			protected Cell topCell;	/** Map of all CellTopologies */				private Map<String,CellNetInfo> cellTopos;	/** Map of all Cell names */					private Map<Cell,String> cellNameMap;													private HierarchyEnumerator.CellInfo lastInfo;	/** Creates a new instance of Topology */	public Topology() {}	/**	 * Write cell to file	 * @return true on error	 */	public boolean writeCell(Cell cell, VarContext context)	{		writeCell(cell, context, new Visitor(this));		return false;	}	/**	 * Write cell to file	 * @return true on error	 */	public boolean writeCell(Cell cell, VarContext context, Visitor visitor)	{		// remember the top-level cell		topCell = cell;		// clear the map of CellNetInfo for each processed cell		cellTopos = new HashMap<String,CellNetInfo>();		// make a map of cell names to use (unique across libraries)		cellNameMap = makeCellNameMap(topCell);		// write out cells		start();		HierarchyEnumerator.enumerateCell(cell, context, visitor, getShortResistors());		done();		return false;	}	/** Abstract method called before hierarchy traversal */	protected abstract void start();	/** Abstract method called after traversal */	protected abstract void done();	/** Called at the end of the enter cell phase of hierarchy enumeration */	protected void enterCell(HierarchyEnumerator.CellInfo info) { }	/** Abstract method to write CellGeom to disk */	protected abstract void writeCellTopology(Cell cell, CellNetInfo cni, VarContext context, Topology.MyCellInfo info);	/** Abstract method to convert a network name to one that is safe for this format */	protected abstract String getSafeNetName(String name, boolean bus);	/** Abstract method to convert a cell name to one that is safe for this format */	protected abstract String getSafeCellName(String name);	/** Abstract method to return the proper name of Power (or null to use existing name) */	protected abstract String getPowerName(Network net);	/** Abstract method to return the proper name of Ground (or null to use existing name) */	protected abstract String getGroundName(Network net);	/** Abstract method to return the proper name of a Global signal */	protected abstract String getGlobalName(Global glob);	/**	 * Abstract method to decide whether export names take precedence over	 * arc names when determining the name of the network.	 */	protected abstract boolean isNetworksUseExportedNames();	/** Abstract method to decide whether library names are always prepended to cell names. */	protected abstract boolean isLibraryNameAlwaysAddedToCellName();	/** Abstract method to decide whether aggregate names (busses) are used. */	protected abstract boolean isAggregateNamesSupported();	/** Abstract method to decide whether aggregate names (busses) can have gaps in their ranges. */	protected abstract boolean isAggregateNameGapsSupported();	/** Method to decide whether to choose best export name among exports connected to signal. */	protected boolean isChooseBestExportName() { return true; }	/** Abstract method to decide whether aggregate names (busses) are used. */	protected abstract boolean isSeparateInputAndOutput();	/** Abstract method to decide whether netlister is case-sensitive (Verilog) or not (Spice). */	protected abstract boolean isCaseSensitive();	/**	 * If the netlister has requirments not to netlist certain cells and their	 * subcells, override this method.	 */	protected boolean skipCellAndSubcells(Cell cell) { return false; }	/**	 * If a cell is skipped, this method can perform any checking to	 * validate that no error occurs	 */	protected void validateSkippedCell(HierarchyEnumerator.CellInfo info) { }	/**	 * Method to tell whether the topological analysis should mangle cell names that are parameterized.	 */	protected boolean canParameterizeNames() { return false; }	/** Tell the Hierarchy enumerator how to short resistors */	protected Netlist.ShortResistors getShortResistors() { return Netlist.ShortResistors.NO; }	/** Tell the Hierarchy enumerator whether or not to short parasitic resistors */	protected boolean isShortResistors() { return getShortResistors() != Netlist.ShortResistors.NO; }	/** Tell the Hierarchy enumerator whether or not to short explicit (poly) resistors */	protected boolean isShortExplicitResistors() { return getShortResistors() == Netlist.ShortResistors.ALL; }	/**	 * Method to tell set a limit on the number of characters in a name.	 * @return the limit to name size (0 if no limit).	 */	protected int maxNameLength() { return 0; }	/** Abstract method to convert a cell name to one that is safe for this format */	protected CellNetInfo getCellNetInfo(String cellName)	{		CellNetInfo cni = cellTopos.get(cellName);		return cni;	}	/** Used to switch from schematic enumeration to layout enumeration */	protected boolean enumerateLayoutView(Cell cell) { return false; }	//------------------ override for HierarchyEnumerator.Visitor ----------------------	public class MyCellInfo extends HierarchyEnumerator.CellInfo	{		String currentInstanceParametizedName;	}	public class Visitor extends HierarchyEnumerator.Visitor	{		/** Topology object this Visitor is enumerating for */	private Topology outGeom;		public Visitor(Topology outGeom)		{			this.outGeom = outGeom;		}		public boolean enterCell(HierarchyEnumerator.CellInfo info)		{			if (skipCellAndSubcells(info.getCell()))			{				if (!info.isRootCell())				{					// save subcell topology, even though the cell isn't being written					HierarchyEnumerator.CellInfo parentInfo = info.getParentInfo();					Nodable no = info.getParentInst();					String parameterizedName = parameterizedName(no, parentInfo.getContext());					CellNetInfo cni = getNetworkInformation(info.getCell(), false, parameterizedName,						isNetworksUseExportedNames(), info);					cellTopos.put(parameterizedName, cni);				}				validateSkippedCell(info);				return false;			}			outGeom.enterCell(info);			return true;		}		public void exitCell(HierarchyEnumerator.CellInfo info)		{			// write cell			Cell cell = info.getCell();			CellNetInfo cni = null;			if (info.isRootCell())			{				cni = getNetworkInformation(cell, false, getSafeCellName(cell.getName()),					isNetworksUseExportedNames(), info);				cellTopos.put(cell.getName(), cni);			} else			{				// derived parameterized name of instance of this cell in parent				HierarchyEnumerator.CellInfo parentInfo = info.getParentInfo();				Nodable no = info.getParentInst();				String parameterizedName = parameterizedName(no, parentInfo.getContext());				cni = getNetworkInformation(info.getCell(), false, parameterizedName,					isNetworksUseExportedNames(), info);				cellTopos.put(parameterizedName, cni);			}			outGeom.writeCellTopology(cell, cni, info.getContext(), (MyCellInfo)info);			lastInfo = info;		}		public boolean visitNodeInst(Nodable no, HierarchyEnumerator.CellInfo info)		{			if (!no.isCellInstance()) return false;			VarContext context = info.getContext();			String parameterizedName = parameterizedName(no, context);			if (cellTopos.containsKey(parameterizedName)) return false;	// already processed this Cell			Cell cell = (Cell)no.getProto();			Cell schcell = cell.contentsView();			if (schcell == null) schcell = cell;			if (cell.isSchematic() && enumerateLayoutView(schcell)) {				Cell layCell = null;				for (Iterator<Cell> it = cell.getCellGroup().getCells(); it.hasNext(); ) {					Cell c = it.next();					if (c.getView() == View.LAYOUT) {						layCell = c;						break;					}				}				if (layCell != null) {					HierarchyEnumerator.enumerateCell(layCell, context, this);					// save subcell topology, even though the cell isn't being written					CellNetInfo cni = getNetworkInformation(layCell, false, layCell.getName(),						isNetworksUseExportedNames(), lastInfo);					cellTopos.put(parameterizedName, cni);					return false;				}			}			// else just a cell			return true;		}		public HierarchyEnumerator.CellInfo newCellInfo()		{			return new MyCellInfo();		}	}	//---------------------------- Utility Methods --------------------------------------	/**	 * Class to describe a single signal in a Cell.	 */	protected static class CellSignal	{		/** name to use for this network. */		private String name;		/** Network for this signal. */				private Network net;		/** CellAggregate that this is part of. */	private CellAggregateSignal aggregateSignal;		/** export that this is part of. */			private Export pp;		/** if export is bussed, index of signal */ private int ppIndex;		/** true if part of a descending bus */		private boolean descending;		/** true if a power signal */				private boolean power;		/** true if a ground signal */				private boolean ground;		/** true if from a global signal */			private Global globalSignal;		protected String getName() { return name; }		protected Network getNetwork() { return net; }		protected Export getExport() { return pp; }		protected int getExportIndex() { return ppIndex; }		protected CellAggregateSignal getAggregateSignal() { return aggregateSignal; }		protected boolean isDescending() { return descending; }		protected boolean isGlobal() { return globalSignal != null; }		protected Global getGlobal() { return globalSignal; }		protected boolean isPower() { return power; }		protected boolean isGround() { return ground; }		protected boolean isExported() { return pp != null; }	}	/**	 * Class to describe an aggregate signal (a bus) in a Cell.	 * The difference between aggregate signals and busses is that aggregate signals	 * are more sensitive to variations.  For example, a bus may be X[1,2,4,5] but	 * there may be two aggregate signals describing it because of the noncontinuity	 * of the indices (thus, the aggregate signals will be X[1:2] and X_1[4:5]).	 * Some netlisters allow for gaps, in which case they will be described with a	 * single aggregate signal.  Other factors that cause busses to be broken into	 * multiple aggregate signals are:	 * (1) differences in port direction (mixes of input and output, for example)	 * (2) differences in port type (power, ground, global, etc.)	 */	protected static class CellAggregateSignal	{		private String name;		private Export pp;		private int ppIndex;		private int low;		private int high;		private int[] indices;		private boolean supply;		private boolean descending;		private CellSignal [] signals;		/** scratch word for the subclass */	private int flags;		protected String getName() { return name; }		protected String getNameWithIndices()		{			if (low > high) return name;			if (indices != null)			{				StringBuffer sb = new StringBuffer();				sb.append(name);				sb.append('[');				for(int i=0; i<indices.length; i++)				{					if (i != 0) sb.append(',');					sb.append(indices[i]);				}				sb.append(']');				return sb.toString();			}			int lowIndex = low, highIndex = high;			if (descending)			{				lowIndex = high;   highIndex = low;			}			return name + "[" + lowIndex + ":" + highIndex + "]";		}		protected int getNumSignals() { return signals.length; }		protected CellSignal getSignal(int index) { return signals[index]; }		protected boolean isDescending() { return descending; }		protected boolean isSupply() { return supply; }		protected Export getExport() { return pp; }		protected int getExportIndex() { return ppIndex; }		protected int [] getIndices() { return indices; }		protected int getLowIndex() { return low; }		protected int getHighIndex() { return high; }		protected int getFlags() { return flags; }		protected void setFlags(int flags) { this.flags = flags; }		protected boolean isGlobal()		{			int numGlobal = 0;			for(int i=0; i<signals.length; i++)			{				CellSignal cs = signals[i];				if (cs.isGlobal()) numGlobal++;			}			if (numGlobal > 0 && numGlobal == signals.length) return true;			return false;		}	}	/**	 * Class to describe the networks in a Cell.	 * This contains all of the CellSignal and CellAggregateSignal information.	 */	protected static class CellNetInfo	{		private Cell cell;		private String paramName;		private Map<Network,CellSignal> cellSignals;		private List<CellSignal> cellSignalsSorted;		private List<CellAggregateSignal> cellAggregateSignals;		private Network pwrNet;		private Network gndNet;		private Netlist netList;		protected CellSignal getCellSignal(Network net) { return cellSignals.get(net); }		protected Iterator<CellSignal> getCellSignals() { return cellSignalsSorted.iterator(); }		protected Iterator<CellAggregateSignal> getCellAggregateSignals() { return cellAggregateSignals.iterator(); }		protected String getParameterizedName() { return paramName; }		protected Network getPowerNet() { return pwrNet; }		protected Network getGroundNet() { return gndNet; }		protected Netlist getNetList() { return netList; }		protected Cell getCell() { return cell; }	}	private CellNetInfo getNetworkInformation(Cell cell, boolean quiet, String paramName, boolean useExportedName,		HierarchyEnumerator.CellInfo info)	{		CellNetInfo cni = doGetNetworks(cell, quiet, paramName, useExportedName, info);		if (DEBUGTOPOLOGY)		{			printWriter.println("********Decomposition of " + cell);			printWriter.println("** Have " + cni.cellSignalsSorted.size() + " signals:");			for(Iterator<CellSignal> it = cni.getCellSignals(); it.hasNext(); )			{				CellSignal cs = it.next();				printWriter.println("**   Name="+cs.name+" export="+cs.pp+" index="+cs.ppIndex+" descending="+cs.descending+" power="+cs.power+" ground="+cs.ground+" global="+cs.globalSignal);

⌨️ 快捷键说明

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