?? hspiceout.java
字號:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: HSpiceOut.java * Input/output tool: reader for HSpice output (tr, pa, ac, sw, mt) * Written by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2004 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.hierarchy.Cell;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.Analysis;import com.sun.electric.tool.simulation.ComplexWaveform;import com.sun.electric.tool.simulation.Stimuli;import com.sun.electric.tool.simulation.Waveform;import com.sun.electric.tool.simulation.WaveformImpl;import java.io.File;import java.io.IOException;import java.net.URL;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;/** * Class for reading and displaying waveforms from HSpice output. * This includes transient information in .tr and .pa files (.pa0/.tr0, .pa1/.tr1, ...) * It also includes AC analysis in .ac files; DC analysis in .sw files; * and Measurements in .mt files. * * While trying to debug the condition count handling, these test cases were observed: * CASE VERSION ANALYSIS NUMNOI SWEEPCNT CNDCNT CONDITIONS * H01 9007 TR 0 4 1 bma_w * H02 9007 TR 36 19 1 sweepv * H03 9007 TR 2 30 1 MONTE_CARLO * DC 258 30 1 MONTE_CARLO * H04 9007 TR 2 7 1 TEMPERATURE * DC 0 0 0 * AC 0 6 1 bigcap * H05 9601 TR 0 0 0 * H06 9601 TR 0 0 0 * H07 9601 TR 2 25 3 data_tim, inbufstr, outloadstr (sweep header has 2 numbers) * H08 9601 TR 4 3 2 ccdata, cc * AC 4 2 1 lpvar (***CRASHES***) * H09 9601 TR 0 3 3 rdata, r, c (sweep header has 2 numbers) * AC 0 3 3 rdata, r, c (sweep header has 2 numbers) * H10 9601 TR 0 4 8 rdata, r0, r1, r2, r3, r4, c0, c1 (sweep header has 7 numbers) * AC 0 4 8 rdata, r0, r1, r2, r3, r4, c0, c1 (sweep header has 7 numbers) */public class HSpiceOut extends Simulate{ private static final boolean DEBUGCONDITIONS = false; /** true if tr/ac/sw file is binary */ private boolean isTRACDCBinary; /** true if binary tr/ac/sw file has bytes swapped */ private boolean isTRACDCBinarySwapped; /** the raw file base */ private String fileBase; /** the "tr" file extension (tr0, tr1, ...): transient */ private String trExtension; /** the "sw" file extension (sw0, sw1, ...): DC */ private String swExtension; /** the "ic" file extension (ic0, ic1, ...): old DC */ private String icExtension; /** the "ac" file extension (ac0, ac1, ...): AC */ private String acExtension; /** the "mt" file extension (mt0, mt1, ...): measurement */ private String mtExtension; /** the "pa" file extension (pa0, pa1, ...): long names */ private String paExtension; private int binaryTRACDCSize, binaryTRACDCPosition; private boolean eofReached; private byte [] binaryTRACDCBuffer; /** * Class to hold HSpice name associations from the .paX file */ private static class PALine { int number; String string; } private static class SweepAnalysis extends AnalogAnalysis { double [][] commonTime; // sweep, signal List<List<float[]>> theSweeps = new ArrayList<List<float[]>>(); // sweep, event, signal private SweepAnalysis(Stimuli sd, AnalogAnalysis.AnalysisType type) { super(sd, type, false); } protected Waveform[] loadWaveforms(AnalogSignal signal) { int sigIndex = signal.getIndexInAnalysis(); Waveform[] waveforms = new Waveform[commonTime.length]; for (int sweep = 0; sweep < waveforms.length; sweep++) { double[] times = commonTime[sweep]; List<float[]> theSweep = theSweeps.get(sweep); Waveform waveform; if (getAnalysisType() == ANALYSIS_AC) { double[] realValues = new double[times.length]; double[] imagValues = new double[times.length]; for (int eventNum = 0; eventNum < realValues.length; eventNum++) { float[] eventValues = theSweep.get(eventNum); realValues[eventNum] = eventValues[sigIndex*2 + 1]; imagValues[eventNum] = eventValues[sigIndex*2 + 2]; } waveform = new ComplexWaveform(times, realValues, imagValues); } else { double[] values = new double[times.length]; for (int eventNum = 0; eventNum < values.length; eventNum++) values[eventNum] = theSweep.get(eventNum)[sigIndex + 1]; waveform = new WaveformImpl(times, values); } waveforms[sweep] = waveform; } return waveforms; } } HSpiceOut() {} /** * Method to read HSpice output files. * @param fileURL the URL to one of the output files. * @param cell the Cell associated with these HSpice output files. */ protected Stimuli readSimulationOutput(URL fileURL, Cell cell) throws IOException { // create the Stimuli object Stimuli sd = new Stimuli(); sd.setCell(cell); // figure out file names fileBase = fileURL.getFile(); trExtension = "tr0"; swExtension = "sw0"; icExtension = "ic0"; acExtension = "ac0"; mtExtension = "mt0"; paExtension = "pa0"; int dotPos = fileBase.lastIndexOf('.'); if (dotPos > 0) { String extension = fileBase.substring(dotPos+1); fileBase = fileBase.substring(0, dotPos); if (extension.startsWith("tr") || extension.startsWith("sw") || extension.startsWith("ic") || extension.startsWith("ac") || extension.startsWith("mt") || extension.startsWith("pa")) { trExtension = "tr" + extension.substring(2); swExtension = "sw" + extension.substring(2); icExtension = "ic" + extension.substring(2); acExtension = "ac" + extension.substring(2); mtExtension = "mt" + extension.substring(2); paExtension = "pa" + extension.substring(2); } } // the .pa file has name information List<PALine> paList = readPAFile(fileURL); // read Transient analysis data (.tr file) addTRData(sd, paList, fileURL); // read DC analysis data (.sw file) addDCData(sd, paList, fileURL); // read AC analysis data (.ac file) addACData(sd, paList, fileURL); // read measurement data (.mt file) addMeasurementData(sd, fileURL); // return the simulation data return sd; } /** * Method to find the ".mt" file and read measurement data. * @param sd the Stimuli to add this measurement data to. * @param fileURL the URL to the ".tr" file. * @throws IOException */ private void addMeasurementData(Stimuli sd, URL fileURL) throws IOException { // find the associated ".mt" name file URL mtURL = null; try { mtURL = new URL(fileURL.getProtocol(), fileURL.getHost(), fileURL.getPort(), fileBase + "." + mtExtension); } catch (java.net.MalformedURLException e) { } if (mtURL == null) return; if (!TextUtils.URLExists(mtURL)) return; if (openTextInput(mtURL)) return; System.out.println("Reading HSpice measurements '" + mtURL.getFile() + "'"); AnalogAnalysis an = new AnalogAnalysis(sd, AnalogAnalysis.ANALYSIS_MEAS, false); List<String> measurementNames = new ArrayList<String>(); HashMap<String,List<Double>> measurementData = new HashMap<String,List<Double>>(); String lastLine = null; for(;;) { // get line from file String nextLine = lastLine; if (nextLine == null) { nextLine = lineReader.readLine(); if (nextLine == null) break; } if (nextLine.startsWith("$") || nextLine.startsWith(".")) continue; String [] keywords = breakMTLine(nextLine, false); if (keywords.length == 0) break; // gather measurement names on the first time out if (measurementNames.size() == 0) { for(int i=0; i<keywords.length; i++) measurementNames.add(keywords[i]); for(;;) { lastLine = lineReader.readLine(); if (lastLine == null) break; keywords = breakMTLine(lastLine, true); if (keywords.length == 0) { lastLine = null; break; } if (TextUtils.isANumber(keywords[0])) break; for(int i=0; i<keywords.length; i++) if (keywords[i].length() > 0) measurementNames.add(keywords[i]); } for(String mName : measurementNames) { measurementData.put(mName, new ArrayList<Double>()); } continue; } // get data values int index = 0; for(int i=0; i<keywords.length; i++) { if (keywords[i].length() == 0) continue; String mName = measurementNames.get(index++); List<Double> mData = measurementData.get(mName); mData.add(new Double(TextUtils.atof(keywords[i]))); } for(;;) { if (index >= measurementNames.size()) break; lastLine = lineReader.readLine(); if (lastLine == null) break; keywords = breakMTLine(lastLine, true); if (keywords.length == 0) break; for(int i=0; i<keywords.length; i++) { if (keywords[i].length() == 0) continue; String mName = measurementNames.get(index++); List<Double> mData = measurementData.get(mName); mData.add(new Double(TextUtils.atof(keywords[i]))); } } lastLine = null; continue; } // convert this to a list of Measurements List<Double> argMeas = measurementData.get(measurementNames.get(0)); an.buildCommonTime(argMeas.size()); for (int i = 0; i < argMeas.size(); i++) an.setCommonTime(i, argMeas.get(i).doubleValue()); List<AnalogSignal> measData = new ArrayList<AnalogSignal>(); for(String mName : measurementNames) { List<Double> mData = measurementData.get(mName); double[] values = new double[mData.size()]; for(int i=0; i<mData.size(); i++) values[i] = mData.get(i).doubleValue(); // special case with the "alter#" name...remove the "#" if (mName.equals("alter#")) mName = "alter"; AnalogSignal as = an.addSignal(mName, null, values); measData.add(as); } closeInput(); } /** * Method to parse a line from a measurement (.mt0) file. * @param line the line from the file. * @param continuation true if the line is supposed to be a continuation * after the first line. * @return an array of strings on the line (zero-length if at end). */ private String[] breakMTLine(String line, boolean continuation) { List<String> strings = new ArrayList<String>(); for(int i=1; ; ) { if (line.length() <= i+1) break; int end = i+17; if (end > line.length()) end = line.length(); while (end < line.length() && line.charAt(end-1) != ' ') end++; String part = line.substring(i, end).trim();// if (i == 1)// {// // first token: make sure it is blank if a continuation// if (continuation && part.length() > 0) return new String[0];// } if (part.length() > 0) strings.add(part.trim()); i = end; } int actualSize = strings.size(); String [] retVal = new String[actualSize]; for(int i=0; i<actualSize; i++) retVal[i] = strings.get(i); return retVal; } /** * Method to find the ".tr" file and read transient data. * @param sd the Stimuli to add this transient data to. * @param fileURL the URL to the ".tr" file. * @throws IOException */ private void addTRData(Stimuli sd, List<PALine> paList, URL fileURL) throws IOException { // find the associated ".tr" name file URL swURL = null; try { swURL = new URL(fileURL.getProtocol(), fileURL.getHost(), fileURL.getPort(), fileBase + "." + trExtension); } catch (java.net.MalformedURLException e) {} if (swURL == null) return; if (!TextUtils.URLExists(swURL)) return; // process the DC data readTRDCACFile(sd, swURL, paList, Analysis.ANALYSIS_TRANS); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -