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

📄 epicreaderprocess.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: EpicReaderProcess.java * Input/output tool: external reader for EPIC output (.out) * * 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 java.io.BufferedOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.regex.Pattern;/** * This class is a launched in external JVM to read Epic output file. * It doesn't import other Electric modules. * Waveforms are stored in temporary file. * Signal names are passed to std out using the following syntax: * StdOut :== signames resolutions signalInfo* fileName * signames :== ( up | down | signal )* 'F'  * up :== 'U' * down :== 'D' stringRef * signal :== ( 'V' | 'I' ) stringRef * stringRef= INT [ UDF ] * resolutions :== timeResolution voltageResolution currentResolution timeMax * timeResolution :== DOUBLE * voltageResolution :== DOUBLE * currentResolution :== DOUBLE * timeMax :== DOUBLE * signalInfo :== minV maxV packedLength * minV :== INT * maxV :== INT * packedLength :== INT * fileName :== UDF * * Inititially current context i sempty. * 'D' pushes a string to it. * 'U' pops a string. * 'V' and 'I' use the current context. * * stringRef  starts with a number. If this number is a new number then it is followed by definition of this string, * otherwise it is reference of previously defined string. * Number of signalInfo is equal to number of defined signals. * fileName is a name of temporary file on local machine with packed waveform data. * length in signalInfo is a number of bytes occupied in the file by this signal. */class EpicReaderProcess {    /** Input stream with Epic data. */                         private InputStream inputStream;    /** File length of inputStream. */                          private long fileLength;    /** Number of bytes read from stream to buffer. */          private long byteCount;    /** Buffer for parsing. */                                  private byte[] buf = new byte[65536];    /** Count of valid bytes in buffer. */                      private int bufL;    /** Count of parsed bytes in buffer. */                     private int bufP;    /** Count of parsed lines. */                               private int lineNum;    /** String builder to build input line. */                  private StringBuilder builder = new StringBuilder();    /** Pattern used to split input line into pieces. */        private Pattern whiteSpace = Pattern.compile("[ \t]+");    /** Last value of progress indicater (percents(.*/          private byte lastProgress;         /** A map from Strings to Integer ids. */                   private HashMap<String,Integer> stringIds = new HashMap<String,Integer>();    /** Chronological list of signals. */                       private ArrayList<EpicReaderSignal> signals = new ArrayList<EpicReaderSignal>();    /** Sparce list to access signals by their Epic indices. */ private ArrayList<EpicReaderSignal> signalsByEpicIndex = new ArrayList<EpicReaderSignal>();    /** Time resolution from input file. */                     private double timeResolution;    /** Voltage resolution from input file. */                  private double voltageResolution;    /** Current resolution from input file. */                  private double currentResolution;    /** Current time (in integer units). */                     private int curTime = 0;    /** A stack of signal context pieces. */                    private ArrayList<String> contextStack = new ArrayList<String>();    /** Count of timepoints for statistics. */                  private int timesC = 0;    /** Count of signal events for statistics. */               private int eventsC = 0;        /* DataOutputStream view of standard output. */             private DataOutputStream stdOut = new DataOutputStream(System.out);    /** Epic format we are able to read. */                     private static final String VERSION_STRING = ";! output_format 5.3";    /** Epic separator char. */                                 private static final char separator = '.';        /** Private constructor. */    private EpicReaderProcess() {}    /**     * Main program of external JVM for reading Epic files.     */    public static void main(String args[]) {        try {            EpicReaderProcess process = new EpicReaderProcess();            try {                process.readEpic(args[0]);            } catch (IOException e) {                System.err.println("Failed to read " + args[0]);                e.printStackTrace(System.err);                System.exit(1);            }             process.writeOut();        } catch (OutOfMemoryError e) {            System.err.println("Out of memory. Increase memory limit in preferences.");            e.printStackTrace(System.err);            System.exit(2);        } catch (Throwable e) {            e.printStackTrace(System.err);            System.exit(3);        }    }        /**     * Reads Epic file into memory.     * Writes signal names to stdout.      * @param urlName url name of Epic file.     */    private void readEpic(String urlName) throws IOException {        URL fileURL = new URL(urlName);        long startTime = System.currentTimeMillis();		URLConnection urlCon = fileURL.openConnection();        urlCon.setConnectTimeout(10000);        urlCon.setReadTimeout(1000);        String contentLength = urlCon.getHeaderField("content-length");        fileLength = -1;        try {            fileLength = Long.parseLong(contentLength);        } catch (Exception e) {}        inputStream = urlCon.getInputStream();		byteCount = 0;        String firstLine = getLine();        if (firstLine == null || !firstLine.equals(VERSION_STRING)) {            message("Unknown Epic Version: " + firstLine);        }        for (;;) {            if (bufP >= bufL && readBuf()) break;            int startLine = bufP;            if (parseNumLineFast()) continue;            bufP = startLine;            String line = getLine();            assert bufP <= bufL;            if (line == null) break;            parseNumLine(line);        }        writeContext("");        inputStream.close();                long stopTime = System.currentTimeMillis();        System.err.println((stopTime - startTime)/1000.0 + " sec to read " + byteCount + " bytes " + signals.size() + " signals " + stringIds.size() + " strings " +                 timesC + " timepoints " +  eventsC + " events from " + urlName);    }    /**     * Parses line from Epic file.     */    private void parseNumLine(String line) throws IOException {        if (line.length() == 0) return;        char ch = line.charAt(0);        if (ch == '.') {            String[] split = whiteSpace.split(line);            if (split[0].equals(".index") && split.length == 4) {                byte type;                if (split[3].equals("v"))                    type = 'V';                else if (split[3].equals("i"))                    type = 'I';                else {                    message("Unknown waveform type: " + line);                    return;                }                String name = split[1];                int sigNum = atoi(split[2]);                while (signalsByEpicIndex.size() <= sigNum)                    signalsByEpicIndex.add(null);                EpicReaderSignal s = signalsByEpicIndex.get(sigNum);                if (s == null) {                    s = new EpicReaderSignal();                    signalsByEpicIndex.set(sigNum, s);                    signals.add(s);                }                                // name the signal                if (name.startsWith("v(") && name.endsWith(")")) {                    name = name.substring(2, name.length() - 1);                } else if (name.startsWith("i(") && name.endsWith(")")) {                    name = name.substring(2, name.length() - 1);                } else if (name.startsWith("i1(") && name.endsWith(")")) {                    name = name.substring(3, name.length() - 1);                }                int lastSlashPos = name.lastIndexOf(separator);                String contextName = "";                if (lastSlashPos > 0) {                    contextName = name.substring(0, lastSlashPos + 1);                }                name = name.substring(lastSlashPos + 1);                if (type == 'I') name = "i(" + name + ")";                writeContext(contextName);                stdOut.writeByte(type);                writeString(name);            } else if (split[0].equals(".vdd") && split.length == 2) {            } else if (split[0].equals(".time_resolution") && split.length == 2) {                timeResolution = atof(split[1]) * 1e-9;            } else if (split[0].equals(".current_resolution") && split.length == 2) {                currentResolution = atof(split[1]);            } else if (split[0].equals(".voltage_resolution") && split.length == 2) {                voltageResolution = atof(split[1]);            } else if (split[0].equals(".high_threshold") && split.length == 2) {            } else if (split[0].equals(".low_threshold") && split.length == 2) {            } else if (split[0].equals(".nnodes") && split.length == 2) {            } else if (split[0].equals(".nelems") && split.length == 2) {            } else if (split[0].equals(".extra_nodes") && split.length == 2) {            } else if (split[0].equals(".bus_notation") && split.length == 4) {            } else if (split[0].equals(".hier_separator") && split.length == 2) {            } else if (split[0].equals(".case") && split.length == 2) {            } else {                message("Unrecognized Epic line: " + line);            }        } else if (ch >= '0' && ch <= '9') {            String[] split = whiteSpace.split(line);            int num = atoi(split[0]);            if (split.length  > 1) {                putValue(num, atoi(split[1]));            } else {                putTime(num);            }        } else if (ch == ';' || Character.isSpaceChar(ch)) {        } else {            message("Unrecognized Epic line: " + line);        }    }        /**     * Writes new context as diff to previous context.     * @param s string with new context.     */    private void writeContext(String s) throws IOException {        int matchSeps = 0;        int pos = 0;        matchLoop:        while (matchSeps < contextStack.size()) {            String si = contextStack.get(matchSeps);            if (pos < s.length() && s.charAt(pos) == 'x')                pos++;            if (pos + si.length() >= s.length() || s.charAt(pos + si.length()) != separator)                break;            for (int k = 0; k < si.length(); k++)                if (s.charAt(pos + k) != si.charAt(k))                    break matchLoop;            matchSeps++;            pos += si.length() + 1;        }        while (contextStack.size() > matchSeps) {            stdOut.writeByte('U');            contextStack.remove(contextStack.size() - 1);        }        assert contextStack.size() == matchSeps;        while (pos < s.length()) {            int indexOfSep = s.indexOf(separator, pos);            assert indexOfSep >= pos;            stdOut.writeByte('D');            if (pos < indexOfSep && s.charAt(pos) == 'x')                pos++;            String si = s.substring(pos, indexOfSep);            writeString(si);            contextStack.add(si);            pos = indexOfSep + 1;        }        assert pos == s.length();    }        /**     * Writes string to stdOut.     * It writes its chronological number.     * It writes string itself, if it is a new string.     * @param s string to write.     */    private void writeString(String s) throws IOException {        if (s == null) {            stdOut.writeInt(-1);            return;        }        Integer i = stringIds.get(s);        if (i != null) {            stdOut.writeInt(i.intValue());            return;        }        stdOut.writeInt(stringIds.size());        i = new Integer(stringIds.size());        s = new String(s); // To avoid long char array of substrings        stringIds.put(s, i);        stdOut.writeUTF(s);    }        /**     * Fast routine to parse a line from buffer.     * It either recognizes a simple line or rejects.     * @return true if this method recognized a line.     */    private boolean parseNumLineFast() {        final int MAX_DIGITS = 9;        if (bufP + (MAX_DIGITS*2 + 4) >= bufL) return false;        int ch = buf[bufP++];        if (ch < '0' || ch > '9') return false;        int num1 = ch - '0';        ch = buf[bufP++];        for (int lim = bufP + (MAX_DIGITS - 1); '0' <= ch && ch <= '9' && bufP < lim; ch = buf[bufP++])            num1 = num1*10 + (ch - '0');        boolean twoNumbers = false;        int num2 = 0;        if (ch == ' ') {            ch = buf[bufP++];            boolean sign = false;            if (ch == '-') {                sign = true;                ch = buf[bufP++];            }            if (ch < '0' || ch > '9') return false;            num2 = ch - '0';            ch = buf[bufP++];            for (int lim = bufP + (MAX_DIGITS - 1); '0' <= ch && ch <= '9' && bufP < lim; ch = buf[bufP++])                num2 = num2*10 + (ch - '0');            if (sign) num2 = -num2;            twoNumbers = true;        }        if (ch == '\n') {        } else if (ch == '\r') {            if (buf[bufP] == '\n')

⌨️ 快捷键说明

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