/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: PSpiceOut.java * Input/output tool: reader for PSpice text output (.txt) * Written by Steven M. Rubin, Sun Microsystems. * * 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.hierarchy.Cell; import com.sun.electric.database.text.TextUtils; import com.sun.electric.tool.simulation.AnalogAnalysis; import com.sun.electric.tool.simulation.Stimuli; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Class for reading and displaying waveforms from PSpice and Spice3 output. * These are contained in .txt files. * * Here is an example file: * Time I(Q2:e) I(C1) IB(Q1) IC(Q1) * 0.000000000000e+000 -1.326552010141e-003 0.000000000000e+000 7.693014595134e-006 1.152132987045e-003 * 2.000000000000e-010 -1.327024307102e-003 -6.724173662320e-009 7.738638487353e-006 1.152158598416e-003 */ public class PSpiceOut extends Simulate { PSpiceOut() {} /** * Method to read an PSpice output file. */ protected void readSimulationOutput(Stimuli sd, URL fileURL, Cell cell) throws IOException { // open the file if (openTextInput(fileURL)) return; // show progress reading .spo file startProgressDialog("PSpice output", fileURL.getFile()); // read the actual signal data from the .spo file readPSpiceFile(cell, sd); // stop progress dialog, close the file stopProgressDialog(); closeInput(); } private void readPSpiceFile(Cell cell, Stimuli sd) throws IOException { boolean first = true; AnalogAnalysis an = new AnalogAnalysis(sd, AnalogAnalysis.ANALYSIS_SIGNALS, false); sd.setCell(cell); List<String> signalNames = new ArrayList<String>(); List<Double> [] values = null; int numSignals = 0; for(;;) { String line = getLine(); if (line == null) break; if (first) { // check the first line for HSPICE format possibility first = false; if (line.length() >= 20) { String hsFormat = line.substring(16, 20); if (hsFormat.equals("9007") || hsFormat.equals("9601")) { System.out.println("This is an HSPICE file, not a SPICE3/PSPICE file"); System.out.println("Change the SPICE format (in Preferences) and reread"); return; } } // parse the signal names on the first line int ptr = 0; for(;;) { while (ptr < line.length() && Character.isWhitespace(line.charAt(ptr))) ptr++; if (ptr >= line.length()) break; int start = ptr; while (ptr < line.length() && !Character.isWhitespace(line.charAt(ptr))) ptr++; signalNames.add(line.substring(start, ptr)); } numSignals = signalNames.size(); values = new List[numSignals]; for(int i=0; i<numSignals; i++) values[i] = new ArrayList<Double>(); continue; } // skip first word if there is an "=" in the line int equalPos = line.indexOf("="); if (equalPos >= 0) { if (line.length() > (equalPos+3)) line = line.substring(equalPos+3); else { System.out.println("Missing value after '='. This may not be a PSpice output file."); return; } } // read the data values int ptr = 0; int position = 0; for(;;) { while (ptr < line.length() && Character.isWhitespace(line.charAt(ptr))) ptr++; if (ptr >= line.length() || line.charAt(ptr) == ')') break; int start = ptr; while (ptr < line.length() && !Character.isWhitespace(line.charAt(ptr))) ptr++; double value = TextUtils.atof(line.substring(start, ptr)); values[position++].add(new Double(value)); } if (position != numSignals) { System.out.println("Line of data has " + position + " values, but expect " + numSignals + ". Unable to recover from error. This may not be a PSpice output file."); return; } } // convert lists to arrays if (numSignals == 0) { System.out.println("No data found in the file. This may not be a PSpice output file."); return; } int numEvents = values[0].size(); an.buildCommonTime(numEvents); for(int i=0; i<numEvents; i++) { an.setCommonTime(i, values[0].get(i).doubleValue()); } for(int j=1; j<numSignals; j++) { double[] doubleValues = new double[numEvents]; for(int i=0; i<numEvents; i++) doubleValues[i] = values[j].get(i).doubleValue(); an.addSignal(signalNames.get(j), null, doubleValues); } } }