Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: NccGlobals.java
*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
*
* 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.
*/
/*
* NccGlobals holds all the global state for an Ncc run. All class
* members that were previously static have been moved to this
* class. This allows an Ncc run to be completely thread safe.
*/
package com.sun.electric.tool.ncc;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.HierarchyEnumerator.NetNameProxy;
import com.sun.electric.database.hierarchy.HierarchyEnumerator.NodableNameProxy;
import com.sun.electric.database.variable.VarContext;
import com.sun.electric.tool.ncc.basic.NccUtils;
import com.sun.electric.tool.ncc.netlist.NccNetlist;
import com.sun.electric.tool.ncc.netlist.NetObject;
import com.sun.electric.tool.ncc.netlist.Part;
import com.sun.electric.tool.ncc.netlist.Wire;
import com.sun.electric.tool.ncc.result.BenchmarkResults;
import com.sun.electric.tool.ncc.trees.Circuit;
import com.sun.electric.tool.ncc.trees.EquivRecord;
import com.sun.electric.tool.ncc.trees.LeafEquivRecords;
import com.sun.electric.tool.user.ncc.NccGuiInfo;
import com.sun.electric.tool.Job;
/**
* Generate non-recurring random integers
*/
class NccRandom {
private Random randGen = new Random(204);
private HashSet randoms = new HashSet();
public int next() {
while (true) {
Integer r = new Integer(randGen.nextInt());
if (!randoms.contains(r)) {
randoms.add(r);
return r.intValue();
}
}
}
}
/** I tried to make NCC thread safe. Therefore there are a minimum of
* static variables. Instead, most of what would have been NCC's
* global variables are stored in NccGlobals. A new NccGlobals
* is created every time NccEngine.compare() is started. Therefore two jobs
* can call NCC at the same time without interfering with each
* other.
*/
public class NccGlobals implements NccGlobalsReportable {
// ---------------------------- private data ------------------------------
private static final int CODE_PART= 0;
private static final int CODE_WIRE= 1;
private static final int CODE_PORT= 2;
/** used to assign new hash code values to EquivRecords */
private NccRandom randGen = new NccRandom();
/** all options controlling an Ncc run */ private final NccOptions options;
/** object says when user wants abort */ private final Aborter aborter;
/** root of the EquivRecord tree */ private EquivRecord root;
/** subtree holding parts */ private EquivRecord parts;
/** subtree holding wires */ private EquivRecord wires;
/** subtree holding ports */ private EquivRecord ports;
/** root Cell of each netlist */ private Cell[] rootCells;
/** VarContext of root of each netlist */ private VarContext[] rootContexts;
/** pass number shared by strategies */ public int passNumber;
/** leaf nodes of parts tree */ private LeafEquivRecords partLeafRecs;
/** leaf nodes of wires tree */ private LeafEquivRecords wireLeafRecs;
/** leaf nodes of ports tree */ private LeafEquivRecords portLeafRecs;
/** can't build netlist? */ private boolean[] cantBuildNetlist;
/** mismatches displayed by GUI */ private NccGuiInfo nccGuiInfo;
/** holds performance counters */ private BenchmarkResults benchResults = new BenchmarkResults();
// ----------------------------- private methods --------------------------
private List getNetObjs(int code, NccNetlist nets) {
switch (code) {
case CODE_PART: return nets.getPartArray();
case CODE_WIRE: return nets.getWireArray();
case CODE_PORT: return nets.getPortArray();
}
error("invalid code");
return null;
}
private void countNetObjs(int[] counts, Iterator it) {
while (it.hasNext()) {
EquivRecord er = it.next();
error(!er.isLeaf(), "Must be leaf");
int numCkts = er.numCircuits();
error(counts.length!=numCkts, "different number of Circuits");
Iterator it2 = er.getCircuits();
for (int i=0; i nccNets) {
boolean atLeastOneNetObj = false;
List ckts = new ArrayList();
for (NccNetlist nets : nccNets) {
List netObjs = getNetObjs(code, nets);
if (netObjs.size()!=0) atLeastOneNetObj = true;
ckts.add(Circuit.please(netObjs));
}
if (!atLeastOneNetObj) return null;
return EquivRecord.newLeafRecord(code, ckts, this);
}
// ----------------------------- public methods --------------------------
/**
* The constructor initializes global root, parts, wires, and ports from
* net lists.
* @param options the options controlling how NCC performs the comparison
* @param aborter an object that NCC queries to determine if the user
* wants to abort NCC in the middle of a run.
*/
public NccGlobals(NccOptions options, Aborter aborter) {
this.options = options;
this.aborter = aborter;
nccGuiInfo = new NccGuiInfo();
}
/** A conveniently terse method for printing to Electric's message window */
public void prln(String s) {System.out.println(s); System.out.flush();}
/** A conveniently terse method for printing to Electric's message window */
public void pr(String s) {System.out.print(s); System.out.flush();}
/** Build the initial equivalence record trees from the netlists that are
* to be compared. In principle, NCC can compare more than two netlists
* at the same time, but in practice we've never found a use for this.
* @param nccNets two or more netlists that are supposed to be topologcially
* identical.
*/
public void setInitialNetlists(List nccNets) {
parts = buildEquivRec(CODE_PART, nccNets);
wires = buildEquivRec(CODE_WIRE, nccNets);
ports = buildEquivRec(CODE_PORT, nccNets);
List el = new ArrayList();
if (parts!=null) el.add(parts);
if (wires!=null) el.add(wires);
if (ports!=null) el.add(ports);
root = EquivRecord.newRootRecord(el);
rootCells = new Cell[nccNets.size()];
rootContexts = new VarContext[nccNets.size()];
cantBuildNetlist = new boolean[nccNets.size()];
int i=0;
for (Iterator it=nccNets.iterator(); it.hasNext(); i++) {
NccNetlist nl = it.next();
rootCells[i] = nl.getRootCell();
rootContexts[i] = nl.getRootContext();
cantBuildNetlist[i] = nl.cantBuildNetlist();
}
}
/** Initialization.
* Tricky! initLeafLists() must be called AFTER series/parallel merging.
* and AFTER Local Partitioning!!! Both of those processes violate
* invariants assumed by LeafEquivRecords. */
public void initLeafLists() {
partLeafRecs = new LeafEquivRecords(parts, this);
wireLeafRecs = new LeafEquivRecords(wires, this);
portLeafRecs = new LeafEquivRecords(ports, this);
}
/** get the root of the equivalence record tree */
public EquivRecord getRoot() {return root;}
/** get the root of equivalence record subtree for Parts */
public EquivRecord getParts() {return parts;}
/** get the root of the equivalence record subtree for Wires */
public EquivRecord getWires() {return wires;}
/** get the root of the equivalence record subtree for Ports */
public EquivRecord getPorts() {return ports;}
/** Say how many netlists are being compared. This will usually be two.
* In principle NCC can compare any number of netlists but we've never
* found a use for this feature. */
public int getNumNetlistsBeingCompared() {return rootCells.length;}
/** get an array of root Cells, one per netlist */
public Cell[] getRootCells() {return rootCells;}
/** get an array of VarContexts, one per netlist */
public VarContext[] getRootContexts() {return rootContexts;}
/** get an array of root Cell Names, one per netlist. */
public String[] getRootCellNames() {
String[] rootCellNames = new String[rootCells.length];
for (int i=0; i=1) prln(msg);
}
/** Print less important status messages into the Electric
* messages window. The user selects how verbose NCC is
* using the howMuchStatus option.
* @param msg the message to be printed.
*/
public void status2(String msg) {
if (options.howMuchStatus>=2) prln(msg);
}
/** Flush System.out */
public void flush() {System.out.flush();}
/** Print a message and abort execution if pred is true.
* @param pred if true then an error has occurred
* @param msg message to print when error occurs
*/
public void error(boolean pred, String msg) {
Job.error(pred, msg);
}
/** Print a message and abort execution
* @param msg message to print when error occurs
*/
public void error(String msg) {
Job.error(true, msg);}
/** Get the NCC options.
*/
public NccOptions getOptions() {return options;}
/** Generate non-recurring pseudo-random integers */
public int getRandom() {return randGen.next();}
/** Get the leaf equivalence records of the Part equivalence
* record sub tree
*/
public LeafEquivRecords getPartLeafEquivRecs() {return partLeafRecs;}
/** Get the leaf equivalence records of the Wire equivalence
* record sub tree
*/
public LeafEquivRecords getWireLeafEquivRecs() {return wireLeafRecs;}
/** Get the leaf equivalence records of the Port equivalence
* record sub tree
*/
public LeafEquivRecords getPortLeafEquivRecs() {return portLeafRecs;}
/** @return an NetNameProxy[][]. NetNameProxy[d][n] gives the nth net of
* the dth design. NetNameProxy[a][n] is NCC equivalent to NetNameProxy[b][n]
* for all a and b.*/
public NetNameProxy[][] getEquivalentNets() {
int numDes = getNumNetlistsBeingCompared();
NetNameProxy[][] equivNets = new NetNameProxy[numDes][];
int numMatched = wireLeafRecs.numMatched();
for (int i=0; i it=wireLeafRecs.getMatched(); it.hasNext(); wireNdx++) {
EquivRecord er = it.next();
int cktNdx = 0;
for (Iterator cit=er.getCircuits(); cit.hasNext(); cktNdx++) {
Circuit ckt = cit.next();
Job.error(ckt.numNetObjs()!=1, "not matched?");
Wire w = (Wire) ckt.getNetObjs().next();
equivNets[cktNdx][wireNdx] = w.getNameProxy().getNetNameProxy();
}
}
return equivNets;
}
/** @return an NodableNameProxy[][]. NodableNameProxy[d][n] gives the nth net of
* the dth design. NetNameProxy[a][n] is NCC equivalent to NetNameProxy[b][n]
* for all a and b.*/
public NodableNameProxy[][] getEquivalentNodes() {
int numDes = getNumNetlistsBeingCompared();
NodableNameProxy[][] equivParts = new NodableNameProxy[numDes][];
int numMatched = partLeafRecs.numMatched();
for (int i=0; i it=partLeafRecs.getMatched(); it.hasNext(); partNdx++) {
EquivRecord er = it.next();
int cktNdx = 0;
for (Iterator cit=er.getCircuits(); cit.hasNext(); cktNdx++) {
Circuit ckt = cit.next();
Job.error(ckt.numNetObjs()!=1, "not matched?");
Part p = (Part) ckt.getNetObjs().next();
equivParts[cktNdx][partNdx] = p.getNameProxy().getNodableNameProxy();
}
}
return equivParts;
}
/** Get mismatches to be displayed in the GUI
* @return an object with mismatches to be displayed in GUI */
public NccGuiInfo getNccGuiInfo() {return nccGuiInfo;}
/** @return true if some netlist can't be built */
public boolean cantBuildNetlist() {
for (int i=0; i