/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Simulate.java
* Input/output tool: superclass for simulation-output formats that display their results in a waveform window.
* Written by Steven M. Rubin, Sun Microsystems.
*
* 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.
*/
package com.sun.electric.tool.io.input;
import com.sun.electric.database.Environment;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.EDatabase;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.UserInterfaceExec;
import com.sun.electric.tool.io.FileType;
import com.sun.electric.tool.io.input.verilog.VerilogOut;
import com.sun.electric.tool.simulation.SimulationTool;
import com.sun.electric.tool.simulation.Stimuli;
import com.sun.electric.tool.user.waveform.WaveformWindow;
import com.sun.electric.util.TextUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.swing.SwingUtilities;
/**
* This class reads simulation output files and plots them.
*/
public final class SimulationData {
private SimulationData() {}
private static final String[] known_extensions = new String[]
{
// Steve has specifically requested that tr0/ac0 files have top
// priority (Bug #2815)
"tr0", "ac0",
"vcd", "raw", "dump", "spo",
// it's important that "out" and "txt" appear last because
// they sometimes are present yet do not contain simulation
// data (although in such situations the user should not
// be using "plot from guessed" anyways)
"out", "txt" };
public static boolean isKnownSimulationFormatExtension(String extension) {
return getInputForExtension(extension)!=null;
}
/**
* Based on the provided cell, make an educated guess
* about which simulation file the user has in mind, and plot
* that. If WaveformWindow is null, one will be created.
*/
public static void plotGuessed(Cell cell, WaveformWindow ww) {
if (cell==null) return;
String[] paths = new String[] {
FileType.SPICE.getGroupPath(),
TextUtils.getFilePath(cell.getLibrary().getLibFile())
};
for (String path : paths)
for (String ext : known_extensions)
if (new File(path, cell.getName()+'.'+ext).exists()) {
plot(cell, TextUtils.makeURLToFile(new File(path, cell.getName()+'.'+ext).getPath()), ww);
return;
}
System.out.println("unable to guess any simulation file with a known extension; the following directories were checked: ");
for(String path : paths)
System.out.println(" " + path);
}
/**
* Plot the simulation data for cell found at url in ww.
* If cell is null, no cell will be associated with the simulation data (crossprobing disabled).
* If ww is null, a waveform window will be created.
*/
public static void plot(Cell cell, URL url, WaveformWindow ww) {
new ReadSimulationOutput(cell, url, ww).start();
}
private static Input<Stimuli> getInputForExtension(String extension) {
if (extension.indexOf('.') != -1)
extension = extension.substring(extension.lastIndexOf('.')+1);
if (extension.equals("dump") || extension.equals("vcd")) return new VerilogOut();
if (extension.equals("txt")) return new PSpiceOut();
if (extension.equals("raw")) return new RawSpiceOut();
if (extension.equals("spo")) return new SpiceOut();
if (extension.equals("out")) return new EpicOut();
if (extension.startsWith("tr") || extension.startsWith("sw") || extension.startsWith("ic") ||
extension.startsWith("ac") || extension.startsWith("mt") || extension.startsWith("pa"))
return new HSpiceOut();
return null;
}
/**
* Class to read simulation output in a new thread.
*/
private static class ReadSimulationOutput extends Thread {
private Input<Stimuli> is;
private URL fileURL;
private Cell cell;
private WaveformWindow ww;
private Stimuli sd;
private final Environment launcherEnvironment;
private final UserInterfaceExec userInterface;
private String netDelimeter;
private ReadSimulationOutput(Cell cell, URL fileURL, WaveformWindow ww) {
this.fileURL = fileURL;
this.cell = cell;
this.ww = ww;
this.is = getInputForExtension(fileURL.getPath());
this.netDelimeter = SimulationTool.getSpiceExtractedNetDelimiter();
if (this.is==null) throw new RuntimeException("unable to detect type");
launcherEnvironment = Environment.getThreadEnvironment();
userInterface = new UserInterfaceExec();
}
public void run() {
if (is == null) return;
if (Thread.currentThread() == this) {
Environment.setThreadEnvironment(launcherEnvironment);
Job.setUserInterface(userInterface);
}
try {
sd = new Stimuli();
sd.setNetDelimiter(netDelimeter);
sd.setCell(cell);
is.processInput(fileURL, cell, sd);
if (sd == null) return;
sd.setFileURL(fileURL);
final Stimuli sdx = sd;
assert cell.getDatabase() == EDatabase.clientDatabase();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (ww == null)
WaveformWindow.showSimulationDataInNewWindow(sdx);
else
WaveformWindow.refreshSimulationData(sdx, ReadSimulationOutput.this.ww);
}});
} catch (IOException e) {
System.out.println("Error reading: " + fileURL + " (" + e.getMessage() + ")");
}
}
}
public static Stimuli processInput(Cell cell, URL url) {
ReadSimulationOutput job = new ReadSimulationOutput(cell, url, null);
job.run();
return job.sd;
}
public static Stimuli processInput(Cell cell, URL url, String netDelimeter) {
Input<Stimuli> is = getInputForExtension(url.getPath());
if (is==null) throw new RuntimeException("unable to detect type");
Stimuli sd = new Stimuli();
sd.setNetDelimiter(netDelimeter);
sd.setCell(cell);
try {
is.processInput(url, cell, sd);
} catch (IOException e) {
System.out.println("End of file reached while reading " + url);
return null;
}
sd.setFileURL(url);
return sd;
}
}