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

📄 epicanalysis.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: EpicAnalysis.java * * 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.io.input;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.text.TextUtils;import com.sun.electric.tool.simulation.AnalogAnalysis;import com.sun.electric.tool.simulation.AnalogSignal;import com.sun.electric.tool.simulation.Stimuli;import com.sun.electric.tool.simulation.Waveform;import com.sun.electric.tool.simulation.WaveformImpl;import com.sun.electric.tool.user.ActivityLogger;import java.awt.geom.Rectangle2D;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.util.ArrayList;import java.util.Arrays;import java.util.BitSet;import java.util.Collections;import java.util.Comparator;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import java.util.NoSuchElementException;import java.util.Vector;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.TreeNode;import javax.swing.tree.TreePath;/** * Class to define a set of simulation data producet by Epic simulators. * This class differs from Anylisis base class by less memory consumption. * Waveforms are stored in a file in packed form. They are loaded to memory by * denand. Hierarchical structure is reconstructed from Epic flat names into Context objects. * EpicSignals don't store signalContex strings, EpicAnalysis don't have signalNames hash map. * Elements of Context are EpicTreeNodes. They partially implements interface javax.swing.tree.TreeNode . */public class EpicAnalysis extends AnalogAnalysis {        /** Separator in Epic signal names. */              static final char separator = '.';        /** Type of voltage signal. */                      static final byte VOLTAGE_TYPE = 1;    /** Type of current signal. */                      static final byte CURRENT_TYPE = 2;        /** Fake context which denotes voltage signal. */   static final Context VOLTAGE_CONTEXT = new Context(VOLTAGE_TYPE);    /** Fake context which denotes current signal. */   static final Context CURRENT_CONTEXT = new Context(CURRENT_TYPE);        /** File name of File with waveforms. */            private File waveFileName;    /** Opened file with waveforms. */                  private RandomAccessFile waveFile;    /** Offsets of packed waveforms in the file. */     int[] waveStarts;        /** Time resolution of integer time unit. */        private double timeResolution;    /** Voltage resolution of integer voltage unit. */  private double voltageResolution;    /** Current resolution of integer current unit. */  private double currentResolution;    /** Simulation time. */                             private double maxTime;        /** Unmodifieable view of signals list. */          private List<AnalogSignal> signalsUnmodifiable;    /** a set of voltage signals. */                    private BitSet voltageSignals = new BitSet();     /** Top-most context. */                            private Context rootContext;    /** Hash of all contexts. */                        private Context[] contextHash = new Context[1];    /** Count of contexts in the hash. */               private int numContexts = 0;    /**     * Package-private constructor.     * @param sd Stimuli.     */    EpicAnalysis(Stimuli sd) {        super(sd, AnalogAnalysis.ANALYSIS_TRANS, false);        signalsUnmodifiable = Collections.unmodifiableList(super.getSignals());    }        /**     * Set time resolution of this EpicAnalysis.     * @param timeResolution time resolution in nanoseconds.     */    void setTimeResolution(double timeResolution) { this.timeResolution = timeResolution; }        /**     * Set voltage resolution of this EpicAnalysys.     * @param voltageResolution voltage resolution in volts.     */    void setVoltageResolution(double voltageResolution) { this.voltageResolution = voltageResolution; }        /**     * Set current resolution of this EpicAnalysys.     * @param currentResolution in amperes ( milliamperes? ).     */    void setCurrentResolution(double currentResolution) { this.currentResolution = currentResolution; }        double getValueResolution(int signalIndex) {        return voltageSignals.get(signalIndex) ? voltageResolution : currentResolution;    }        /**     * Set simulation time of this EpicAnalysis.     * @param maxTime simulation time in nanoseconds.     */    void setMaxTime(double maxTime) { this.maxTime = maxTime; }        /**     * Set root context of this EpicAnalysys.     * @param context root context.     */    void setRootContext(Context context) { rootContext = context; }        /**     * Set waveform file of this EpicAnalysis.     * @param waveFileName File object with name of waveform file.     */    void setWaveFile(File waveFileName) throws FileNotFoundException {        this.waveFileName = waveFileName;        waveFileName.deleteOnExit();        waveFile = new RandomAccessFile(waveFileName, "r");    }        /**     * Free allocated resources before closing.     */    @Override    public void finished() {        try {            waveFile.close();            waveFileName.delete();        } catch (IOException e) {        }    }    	/**	 * Method to quickly return the signal that corresponds to a given Network name.     * This method overrides the m,ethod from Analysis class.     * It doesn't use signalNames hash map.	 * @param netName the Network name to find.	 * @return the Signal that corresponds with the Network.	 * Returns null if none can be found.	 */    @Override    public AnalogSignal findSignalForNetworkQuickly(String netName) {        AnalogSignal old = super.findSignalForNetworkQuickly(netName);                String lookupName = TextUtils.canonicString(netName);        int index = searchName(lookupName);        if (index < 0) {            assert old == null;            return null;        }        AnalogSignal sig = signalsUnmodifiable.get(index);        return sig;    }    /**     * Public method to build tree of EpicTreeNodes.     * Root of the tree us EpicRootTreeNode objects.     * Deeper nodes are EpicTreeNode objects.     * @param analysis name of root DefaultMutableTreeNode.     * @return root EpicRootTreeNode of the tree.     */	public DefaultMutableTreeNode getSignalsForExplorer(String analysis) {		DefaultMutableTreeNode signalsExplorerTree = new EpicRootTreeNode(this, analysis);        return signalsExplorerTree;    }        /**     * Returns EpicSignal by its TreePath.     * @param treePath specified TreePath.     * @return EpicSignal or null.     */    public static EpicSignal getSignal(TreePath treePath) {        Object[] path = treePath.getPath();        int i = 0;        while (i < path.length && !(path[i] instanceof EpicRootTreeNode))            i++;        if (i >= path.length) return null;        EpicAnalysis an = ((EpicRootTreeNode)path[i]).an;        i++;        int index = 0;        for (; i < path.length; i++) {            EpicTreeNode tn = (EpicTreeNode)path[i];            index += tn.nodeOffset;            if (tn.isLeaf())                return (EpicSignal)an.signalsUnmodifiable.get(index);        }        return null;    }    	/**	 * Method to get the list of signals in this Simulation Data object.     * List is unmodifieable.	 * @return a List of signals.	 */    @Override	public List<AnalogSignal> getSignals() { return signalsUnmodifiable; }    /**     * This methods overrides Analysis.nameSignal.     * It doesn't use Analisys.signalNames to use less memory.     */    @Override	public void nameSignal(AnalogSignal ws, String sigName) {}        /**     * Finds signal index of AnalogSignal with given full name.     * @param name full name.     * @return signal index of AnalogSignal in unmodifiable list of signals or -1.     */    int searchName(String name) {        Context context = rootContext;        for (int pos = 0, index = 0;;) {             int indexOfSep = name.indexOf(separator, pos);            if (indexOfSep < 0) {                EpicTreeNode sig = context.sigs.get(name.substring(pos));                return sig != null ? index + sig.nodeOffset : -1;            }            EpicTreeNode sub = context.subs.get(name.substring(pos, indexOfSep));            if (sub == null) return -1;            context = sub.context;            pos = indexOfSep + 1;            index += sub.nodeOffset;        }    }            /**     * Makes fullName or signalContext of signal with specified index.     * @param index signal index.     * @param full true to request full name.     */    String makeName(int index, boolean full) {        StringBuilder sb = new StringBuilder();        Context context = rootContext;        if (context == null) return null;        if (index < 0 || index >= context.treeSize)            throw new IndexOutOfBoundsException();        for (;;) {            int localIndex = context.localSearch(index);            EpicTreeNode tn = context.nodes[localIndex];            Context subContext = tn.context;            if (subContext.isLeaf()) {                if (full)                    sb.append(tn.name);                else if (sb.length() == 0)                    return null;                else                    sb.setLength(sb.length() - 1);                return sb.toString();            }            sb.append(tn.name);            sb.append(separator);            index -= tn.nodeOffset;            context = subContext;        }    }        /**     * Method to get Fake context of AnalogSignal.     * @param byte physical type of AnalogSignal.     * @return Fake context.     */     static Context getContext(byte type) {        switch (type) {            case VOLTAGE_TYPE:                return VOLTAGE_CONTEXT;            case CURRENT_TYPE:                return CURRENT_CONTEXT;        }        throw new IllegalArgumentException();    }    /**     * Method to get Context by list of names and list of contexts.     * @param strings list of names.     * @param contexts list of contexts.     */    Context getContext(ArrayList<String> strings, ArrayList<Context> contexts) {        assert strings.size() == contexts.size();        int hashCode = Context.hashValue(strings, contexts);                int i = hashCode & 0x7FFFFFFF;        i %= contextHash.length;        for (int j = 1; contextHash[i] != null; j += 2) {            Context c = contextHash[i];            if (c.hashCode == hashCode && c.equals(strings, contexts)) return c;                        i += j;            if (i >= contextHash.length) i -= contextHash.length;        }                // Need to create new context.        if (numContexts*2 <= contextHash.length - 3) {            // create a new CellUsage, if enough space in the hash            Context c = new Context(strings, contexts, hashCode);            contextHash[i] = c;            numContexts++;            return c;        }        // enlarge hash if not        rehash();        return getContext(strings, contexts);    }        /**     * Rehash the context hash.     * @throws IndexOutOfBoundsException on hash overflow.     */    private void rehash() {        int newSize = numContexts*2 + 3;        if (newSize < 0) throw new IndexOutOfBoundsException();        Context[] newHash = new Context[GenMath.primeSince(newSize)];        for (int k = 0; k < contextHash.length; k++) {            Context c = contextHash[k];            if (c == null) continue;            int i = c.hashCode & 0x7FFFFFFF;            i %= newHash.length;            for (int j = 1; newHash[i] != null; j += 2) {                i += j;                if (i >= newHash.length) i -= newHash.length;            }            newHash[i] = c;        }        contextHash = newHash;    }    @Override    protected Waveform[] loadWaveforms(AnalogSignal signal) {        int index = signal.getIndexInAnalysis();        double valueResolution = getValueResolution(index);        int start = waveStarts[index];        int len = waveStarts[index + 1] - start;        byte[] packedWaveform = new byte[len];        try {            waveFile.seek(start);            waveFile.readFully(packedWaveform);        } catch (IOException e) {            ActivityLogger.logException(e);            return new Waveform[] { new WaveformImpl(new double[0], new double[0]) };        }                    int count = 0;        for (int i = 0; i < len; count++) {            int l;            int b = packedWaveform[i++] & 0xff;            if (b < 0xC0)                l = 0;            else if (b < 0xFF)                l = 1;            else                l = 4;            i += l;            b = packedWaveform[i++] & 0xff;            if (b < 0xC0)                l = 0;            else if (b < 0xFF)                l = 1;            else                l = 4;            i += l;        }        double[] time = new double[count];        double[] value = new double[count];        count = 0;        int t = 0;        int v = 0;        for (int i = 0; i < len; count++) {            int l;            int b = packedWaveform[i++] & 0xff;            if (b < 0xC0) {                l = 0;            } else if (b < 0xFF) {                l = 1;                b -= 0xC0;            } else {                l = 4;            }            while (l > 0) {                b = (b << 8) | packedWaveform[i++] & 0xff;                l--;            }            t = t + b;            time[count] = t * timeResolution;            b = packedWaveform[i++] & 0xff;            if (b < 0xC0) {                l = 0;                b -= 0x60;            } else if (b < 0xFF) {                l = 1;                b -= 0xDF;            } else {

⌨️ 快捷键说明

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