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

📄 nccnetlist.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: NccNetlist.java * * Copyright (c) 2003 Sun Microsystems and 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.ncc.netlist;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;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.HierarchyEnumerator.CellInfo;import com.sun.electric.database.hierarchy.HierarchyEnumerator.NetNameProxy;import com.sun.electric.database.hierarchy.HierarchyEnumerator.NodableNameProxy;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.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;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.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.TransistorSize;import com.sun.electric.technology.PrimitiveNode.Function;import com.sun.electric.tool.generator.layout.LayoutLib;import com.sun.electric.tool.ncc.NccGlobals;import com.sun.electric.tool.ncc.basic.NccCellAnnotations;import com.sun.electric.tool.ncc.basic.NccUtils;import com.sun.electric.tool.ncc.basic.TransitiveRelation;import com.sun.electric.tool.ncc.basic.NccCellAnnotations.NamePattern;import com.sun.electric.tool.ncc.netlist.NccNameProxy.PartNameProxy;import com.sun.electric.tool.ncc.netlist.NccNameProxy.WireNameProxy;import com.sun.electric.tool.ncc.processing.HierarchyInfo;import com.sun.electric.tool.ncc.processing.SubcircuitInfo;import com.sun.electric.tool.user.ncc.ExportConflict;import com.sun.electric.tool.user.ncc.NccGuiInfo;import com.sun.electric.tool.user.ncc.UnrecognizedPart;/** * NCC's representation of a netlist. */public class NccNetlist {    public final static Netlist.ShortResistors SHORT_RESISTORS = Netlist.ShortResistors.PARASITIC;	private final NccGlobals globals;	private final Cell rootCell;	private final VarContext rootContext;	private ArrayList<Wire> wires;	private ArrayList<Part> parts;	private ArrayList<Port> ports;	private boolean exportAssertionFailures;	private boolean exportGlobalConflicts;	private boolean badTransistorType;	private boolean userAbort;	// ---------------------------- public methods ---------------------------	public NccNetlist(Cell root, VarContext context, 					  HierarchyInfo hierInfo, boolean blackBox, 					  NccGlobals globals) {		this.globals = globals;		rootCell = root; 		rootContext = context;		try {			Visitor v = new Visitor(globals, hierInfo, blackBox, context);			HierarchyEnumerator.enumerateCell(root.getNetlist(SHORT_RESISTORS), context, v, true);			wires = v.getWireList();			parts = v.getPartList();			ports = v.getPortList();			exportAssertionFailures = v.exportAssertionFailures();			badTransistorType = v.badTransistorType();		} catch (RuntimeException e) {			if (e instanceof ExportGlobalConflict) {				exportGlobalConflicts = true;			} else if (e instanceof UserAbort) {				userAbort = true;			} else {				throw e;			}		}		// if there are net list errors then make net list look empty		if (cantBuildNetlist())		{            wires = new ArrayList<Wire>();			parts = new ArrayList<Part>();			ports = new ArrayList<Port>();		}	}	public ArrayList<Wire> getWireArray() {return wires;}	public ArrayList<Part> getPartArray() {return parts;}	public ArrayList<Port> getPortArray() {return ports;}	public boolean cantBuildNetlist() {		return exportAssertionFailures || exportGlobalConflicts ||		       badTransistorType;	}	public boolean userAbort() {return userAbort;}	public Cell getRootCell() {return rootCell;}	public VarContext getRootContext() {return rootContext;}}class ExportGlobalConflict extends RuntimeException {	static final long serialVersionUID = 0;}class UserAbort extends RuntimeException {	static final long serialVersionUID = 0;}/** map from netID to NCC Wire */class Wires {	private final ArrayList<Wire> wires = new ArrayList<Wire>();	private final String pathPrefix; 	private void growIfNeeded(int ndx) {		while(ndx>wires.size()-1) wires.add(null);	}	/** Construct a Wire table. The mergedNetIDs argument specifies	 * sets of net IDs that should point to the same Wire.	 * @param mergedNetIDs contains sets of net IDs that must be merged	 * into the same Wire. */	public Wires(TransitiveRelation<Integer> mergedNetIDs, CellInfo info, 	             String pathPrefix) {		this.pathPrefix = pathPrefix;		for (Iterator<Set<Integer>> it=mergedNetIDs.getSetsOfRelatives(); it.hasNext();) {			Set<Integer> relatives = it.next();			Iterator<Integer> ni = relatives.iterator();			if (!ni.hasNext()) continue;			int netId = ni.next().intValue();			Wire w = get(netId, info);			while (ni.hasNext()) {				netId = ni.next().intValue();				growIfNeeded(netId);				wires.set(netId, w);			}		}	}	public Wire get(int netID, CellInfo info) {		growIfNeeded(netID);		Wire wire = wires.get(netID);		if (wire==null) {			NetNameProxy np = info.getUniqueNetNameProxy(netID, "/");			WireNameProxy wireNm = new WireNameProxy(np, pathPrefix);			wire = new Wire(wireNm);			wires.set(netID, wire);		}		return wire;	}	// return non-null entries of wires array	// Eliminate duplicated Wires.	public ArrayList<Wire> getWireArray() {		Set<Wire> wireSet = new HashSet<Wire>();		wireSet.addAll(wires);		wireSet.remove(null);		ArrayList<Wire> nonNullWires = new ArrayList<Wire>();		nonNullWires.addAll(wireSet);		return nonNullWires;	}}class NccCellInfo extends CellInfo {	private NccGlobals globals;	// I'm caching the annotations because otherwise every Cell	// instance is going to regenerate annotations for it's parent.	private boolean gotAnnotations = false;	private NccCellAnnotations annotations;		// ----------------------------- public methods ---------------------------	public NccCellInfo(NccGlobals globals) {this.globals=globals;}	public NccCellAnnotations getAnnotations() {		if (!gotAnnotations) 			annotations = NccCellAnnotations.getAnnotations(getCell());		gotAnnotations = true;		return annotations;	}	// Subtle:  Suppose a schematic network has an export on it named "gnd"	// and suppose it is also attached to a global signal "gnd". Then we may	// create two "Ports" for the network, one for the global and one for the	// export. The problem is both these ports have the same name: "gnd". This	// violates the invariant that no two Ports may have the same name. I 	// believe it's better to preserve the invariant by discarding the global 	// "gnd" if there is already an Export named "gnd".	public Iterator<ExportGlobal> getExportsAndGlobals() {		HashMap<String,ExportGlobal> nameToExport = new HashMap<String,ExportGlobal>();		// first collect all exports		for (Iterator<PortProto> it=getCell().getPorts(); it.hasNext();) {			Export e = (Export) it.next();			int[] expNetIDs = getExportNetIDs(e);			for (int i=0; i<expNetIDs.length; i++) {				String nm = e.getNameKey().subname(i).toString();				ExportGlobal eg = 					new ExportGlobal(nm, expNetIDs[i],						             e.getCharacteristic(), 									 getNetlist().getNetwork(e,i), e);				nameToExport.put(nm, eg);			}		}		List<ExportGlobal> expGlob = new ArrayList<ExportGlobal>();		expGlob.addAll(nameToExport.values());		// next collect all the globals		Global.Set globNets = getNetlist().getGlobals();		for (int i=0; i<globNets.size(); i++) {			Global g = globNets.get(i);			String nm = g.getName();			Network net = getNetlist().getNetwork(g);			int netID = getNetID(net);			PortCharacteristic type = globNets.getCharacteristic(g); 			ExportGlobal eg = nameToExport.get(nm);			if (eg!=null) {				// Name collision between an export and a global signal. 				// Discard the global.				if (eg.netID!=netID || eg.type!=type) {					if (eg.netID!=netID) {						globals.prln(							"  Error! Cell: "+getCell().libDescribe()+							" has both an Export and a global signal "+							"named: "+nm+" but their networks differ");												// GUI                        ExportConflict.NetworkConflict conf =                             new ExportConflict.NetworkConflict(getCell(), getContext(),                                    nm, eg.network, net);                        globals.getNccGuiInfo().addNetworkExportConflict(conf);                        					}					if (eg.type!=type) {						globals.prln(							"  Error! Cell: "+getCell().libDescribe()+							" has both an Export and a global signal "+							"named: "+nm+" but their Characteristics differ");						// GUI                        ExportConflict.CharactConflict conf =                             new ExportConflict.CharactConflict(getCell(), getContext(),                                    nm, type.getFullName(), eg.type.getFullName(), eg.getExport());                        globals.getNccGuiInfo().addCharactExportConflict(conf);					}										throw new ExportGlobalConflict();				}			} else {				eg = new ExportGlobal(nm, netID, type, net);				expGlob.add(eg);			}		}		return expGlob.iterator();	}}/** Information from either an Export or a Global signal */class ExportGlobal {	private final Export export;	public final String name;	public final int netID;	public final PortCharacteristic type;	public final Network network;	/** For Export 	 * @param export is needed because this ExportGlobal 	 * might be a piece of bussed Export; for example if this ExportGlobal	 * is foo[1] but is only a part of the Export foo[1:3]. */	public ExportGlobal(String nm, int id, PortCharacteristic ty, Network net,			            Export export) {		this.export=export;  name=nm;  netID=id;  type=ty;  network=net;	}	/** For Global */	public ExportGlobal(String nm, int id, PortCharacteristic ty, Network net) {		export=null; name=nm;  netID=id;  type=ty; network=net;	}	public boolean isExport() {return export!=null;}	public Export getExport() {		LayoutLib.error(export==null, "this is a Global, not an Export!");		return export;	}}class Visitor extends HierarchyEnumerator.Visitor {	// --------------------------- private data -------------------------------	private static final boolean debug = false;	private static final Technology SCHEMATIC = Technology.findTechnology("schematic");	private static final Function4PortTo3Port fourToThree = new Function4PortTo3Port();	private final NccGlobals globals;	/** If I'm building a netlist from a node that isn't at the top of the 	 * design hierarchy then Part and Wire names all share a common prefix.	 * This is VERY annoying to the user. Save the path prefix here so I can	 * remove it whenever I build Parts or Wires. */	private final String pathPrefix;	private boolean exportAssertionFailures = false;	private boolean badPartType = false;	private int depth = 0;	/** map from netID to Wire */	 	private Wires wires;	/** all Parts in the net list */ 	private final ArrayList<Part> parts = new ArrayList<Part>();	/** all ports in the net list */ 	private final ArrayList<Port> ports = new ArrayList<Port>();	/** treat these Cells as primitives */	private final HierarchyInfo hierarchicalCompareInfo;	/** generate only hierarchical comparison information */	private final boolean blackBox;		// --------------------------- private methods ----------------------------	private void error(boolean pred, String msg) {globals.error(pred, msg);}	private String spaces() {		StringBuffer sp = new StringBuffer();		for (int i=0; i<depth; i++)	 sp.append(" ");		return sp.toString();	}	private void addMatchingNetIDs(List<Integer> netIDs, NamePattern pattern, 	                               NccCellInfo rootInfo) {		for (Iterator<ExportGlobal> it=rootInfo.getExportsAndGlobals(); it.hasNext();) {			ExportGlobal eg = it.next();			if (pattern.matches(eg.name)) netIDs.add(new Integer(eg.netID));			 										}	}	private void doExportsConnAnnot(TransitiveRelation<Integer> mergedNetIDs,	                                List<NamePattern> connected, NccCellInfo rootInfo) {		List<Integer> netIDs = new ArrayList<Integer>();		for (NamePattern np : connected) {			addMatchingNetIDs(netIDs, np, rootInfo);		}		for (int i=1; i<netIDs.size(); i++) {			mergedNetIDs.theseAreRelated(netIDs.get(0), netIDs.get(i));		}	}	private void doExportsConnAnnots(TransitiveRelation<Integer> mergedNetIDs,	                                 NccCellInfo rootInfo) {		NccCellAnnotations ann = rootInfo.getAnnotations();		if (ann==null) return;		for (Iterator<List<NamePattern>> it=ann.getExportsConnected(); it.hasNext();) {			doExportsConnAnnot(mergedNetIDs, it.next(), rootInfo);					                                     		}	}	private void initWires(NccCellInfo rootInfo) {		TransitiveRelation<Integer> mergedNetIDs = new TransitiveRelation<Integer>();		doExportsConnAnnots(mergedNetIDs, rootInfo);		wires = new Wires(mergedNetIDs, rootInfo, pathPrefix);	}		private void createPortsFromExports(NccCellInfo rootInfo) {		boolean oneNamePerPort = globals.getOptions().oneNamePerPort;		HashSet<Port> portSet = new HashSet<Port>();		for (Iterator<ExportGlobal> it=rootInfo.getExportsAndGlobals(); it.hasNext();) {			ExportGlobal eg = it.next();			Wire wire = wires.get(eg.netID, rootInfo);			portSet.add(wire.addExport(eg.name, eg.type, oneNamePerPort));		}				for (Port p : portSet) 			ports.add(p);	}		/** Get the Wire that's attached to port pi. The Nodable must be an 	 * instance of a PrimitiveNode. 	 * @return the attached Wire. */	private Wire getWireForPortInst(PortInst pi, CellInfo info) {		NodeInst ni = pi.getNodeInst();		error(ni.isCellInstance(), "not PrimitiveNode");		PortProto pp = pi.getPortProto();		int[] netIDs = info.getPortNetIDs(ni, pp);		error(netIDs.length!=1, "Primitive Port connected to bus?");		return wires.get(netIDs[0], info);	}	

⌨️ 快捷键说明

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