/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: NetworkTool.java * Written by: Dmitry Nadezhin, 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.database.network; import com.sun.electric.database.hierarchy.Export; import com.sun.electric.database.prototype.PortProto; import com.sun.electric.database.text.Pref; import com.sun.electric.database.text.Name; import com.sun.electric.database.text.Setting; import com.sun.electric.database.topology.ArcInst; import com.sun.electric.database.topology.Geometric; import com.sun.electric.database.topology.NodeInst; import com.sun.electric.database.topology.PortInst; import com.sun.electric.database.topology.Connection; import com.sun.electric.tool.Job; import com.sun.electric.tool.JobException; import com.sun.electric.tool.Tool; import com.sun.electric.tool.ToolSettings; import com.sun.electric.tool.user.User; import java.util.Iterator; import java.util.Set; import java.util.HashSet; /** * This is the Network tool. */ public class NetworkTool extends Tool { /** * Signals that a method has been invoked at an illegal or * inappropriate time. In other words, the Java environment or * Java application is not in an appropriate state for the requested * operation. */ public static class NetlistNotReady extends RuntimeException { /** * Constructs an IllegalStateException with no detail message. * A detail message is a String that describes this particular exception. */ public NetlistNotReady() { super("User netlist is not ready"); } /** * Constructs an IllegalStateException with the specified detail * message. A detail message is a String that describes this particular * exception. * * @param s the String that contains a detailed message */ public NetlistNotReady(String s) { super(s); } } /** * Method to renumber the netlists. */ public static void renumberNetlists() { new RenumberJob(); } private static class RenumberJob extends Job { private RenumberJob() { super("Renumber All Networks", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); startJob(); } public boolean doIt() throws JobException { // EDatabase.serverDatabase().getNetworkManager().redoNetworkNumbering(true); return true; } } // ---------------------- private and protected methods ----------------- /** the Network tool. */ private static final NetworkTool tool = new NetworkTool(); /** flag for debug print. */ static boolean debug = false; /** flag for information print. */ static boolean showInfo = true; /** total number of errors for statistics */ public static int totalNumErrors = 0; /** sort keys for sorting network errors */ static final int errorSortNetworks = 0; static final int errorSortNodes = 1; static final int errorSortPorts = 2; /** * The constructor sets up the Network tool. */ public NetworkTool() { super("network"); } public static NetworkTool getNetworkTool() { return tool; } /** * Method to set the level of information that is displayed. * When libraries are being read "quietly", no information should be output. * @param infoOutput true for normal information output, false for quiet. */ public static void setInformationOutput(boolean infoOutput) { showInfo = infoOutput; } /****************************** PUBLIC METHODS ******************************/ /** * Method to retrieve all networks for a portInst. * Used by Highlighter and Connection * @param pi the PortInst being considered. * @param netlist the netlist being searched. * @param nets a set into which all found networks will be added. * @return set the set of found networks. */ public static Set<Network> getNetworksOnPort(PortInst pi, Netlist netlist, Set<Network> nets) { boolean added = false; if (nets == null) { nets = new HashSet<Network>(); } if (!pi.isLinked()) { return nets; } for (Iterator<Connection> aIt = pi.getConnections(); aIt.hasNext();) { Connection con = aIt.next(); ArcInst ai = con.getArc(); int wid = netlist.getBusWidth(ai); for (int i = 0; i < wid; i++) { Network net = netlist.getNetwork(ai, i); if (net != null) { added = true; nets.add(net); } } } if (!added) { // port may be exported, without wire attached, and may // connect by export name to other wires NodeInst ni = pi.getNodeInst(); Set<PortInst> ports = new HashSet<PortInst>(); ports.add(pi); for (Iterator<PortInst> it = ni.getPortInsts(); it.hasNext();) { // several ports on node may be connected together at lower level PortInst otherpi = it.next(); if (otherpi == pi) { continue; } if (netlist.sameNetwork(ni, pi.getPortProto(), ni, otherpi.getPortProto())) { ports.add(otherpi); } } for (Iterator<Export> it = ni.getParent().getExports(); it.hasNext();) { Export export = it.next(); if (ports.contains(export.getOriginalPort())) { Name name = export.getNameKey(); for (int i = 0; i < name.busWidth(); i++) { nets.add(netlist.getNetwork(pi.getNodeInst(), pi.getPortProto(), i)); added = true; } break; } } } if (!added) { PortProto pp = pi.getPortProto(); if (pp instanceof Export) { int wid = netlist.getBusWidth((Export) pp); for (int i = 0; i < wid; i++) { Network net = netlist.getNetwork(pi.getNodeInst(), pp, i); if (net != null) { nets.add(net); } } } else { Network net = netlist.getNetwork(pi); if (net != null) { nets.add(net); } } } return nets; } /** * Method to retrieve all networks on a Geometric object. * @param geom the Geometric being considered. * @param netlist the netlist being searched. * @param nets a set into which all found networks will be added. * @return set the set of found networks. */ public static Set<Network> getNetworks(Geometric geom, Netlist netlist, Set<Network> nets) { if (nets == null) { nets = new HashSet<Network>(); } else { nets.clear(); } if (geom instanceof ArcInst) { nets.add(netlist.getNetwork((ArcInst) geom, 0)); } else { NodeInst ni = (NodeInst) geom; for (Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext();) { PortInst pi = pIt.next(); nets = getNetworksOnPort(pi, netlist, nets); //nets.add(netlist.getNetwork(ni, pi.getPortProto(), 0)); //nets.add(netlist.getNetwork(pi)); } } return nets; } /** * Method to initialize a tool. */ public void init() { setOn(); if (!debug) { return; } System.out.println("NetworkTool.init()"); } /************************* PROJECT PREFERENCES **************************/ /** * Method to tell whether resistors are ignored in the circuit. * When ignored, they appear as a "short", connecting the two sides. * When included, they appear as a component with different networks on either side. * @return true if resistors are ignored in the circuit. */ public static boolean isIgnoreResistors() { return getIgnoreResistorsSetting().getBoolean(); } private static Netlist.ShortResistors isIgnoreResistors_() { return Netlist.ShortResistors.NO; } /** * Returns project preferences to tell whether resistors are ignored in the circuit. * When ignored, they appear as a "short", connecting the two sides. * When included, they appear as a component with different networks on either side. * Returns project preferences to tell whether resistors are ignored in the circuit. */ public static Setting getIgnoreResistorsSetting() { return ToolSettings.getIgnoreResistorsSetting(); } /****************************** OPTIONS ******************************/ private final static boolean BUS_ASCENDING_DEFAULT = false; private static Pref cacheBusAscending = Pref.makeBooleanServerPref("BusAscending", NetworkTool.tool.prefs, BUS_ASCENDING_DEFAULT); /** * Method to tell whether unnamed busses should be numbered ascending. * The alternative is descending. * @return true if unnamed busses should be numbered ascending. */ public static boolean isBusAscending() { return cacheBusAscending.getBoolean(); } /** * Method to set whether unnamed busses should be numbered ascending. * The alternative is descending. * @param a true if unnamed busses should be numbered ascending. */ public static void setBusAscending(boolean a) { cacheBusAscending.setBoolean(a); } /** * Method to tell whether unnamed busses should be numbered ascending, by default. * The alternative is descending. * @return true if unnamed busses should be numbered ascending, by default. */ public static boolean isFactoryBusAscending() { return cacheBusAscending.getBooleanFactoryValue(); } /** * Method to tell whether unnamed busses should be numbered ascending in Netlist Engine. * The alternative is descending. * The method always returns false now. * It can be same as isBusAscending() after Netlist Engine correctly renumbers networks * after change this preference. * @return true if unnamed busses should be numbered ascending. */ public static boolean isBusAscendingInNetlistEngine() { // return cacheBusAscending.getBoolean(); return BUS_ASCENDING_DEFAULT; } }