📄 spice.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Spice.java * Original C Code written by Steven M. Rubin and Sid Penstone * Translated to Java 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.output;import com.sun.electric.database.geometry.GeometryHandler;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.geometry.PolyMerge;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.HierarchyEnumerator;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.network.Global;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.text.Version;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.CodeExpression;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Foundry;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitiveNodeSize;import com.sun.electric.technology.Technology;import com.sun.electric.technology.TransistorSize;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.generator.sclibrary.SCLibraryGen;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.io.input.Simulate;import com.sun.electric.tool.io.input.spicenetlist.SpiceNetlistReader;import com.sun.electric.tool.io.input.spicenetlist.SpiceSubckt;import com.sun.electric.tool.ncc.basic.NccCellAnnotations;import com.sun.electric.tool.ncc.basic.NccCellAnnotations.NamePattern;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.user.Exec;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.dialogs.ExecDialog;import com.sun.electric.tool.user.ui.TopLevel;import com.sun.electric.tool.user.waveform.WaveformWindow;import java.awt.geom.AffineTransform;import java.io.BufferedWriter;import java.io.File;import java.io.FileNotFoundException;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.net.URL;import java.util.ArrayList;import java.util.Collections;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;/** * This is the Simulation Interface tool. */public class Spice extends Topology{ private static final boolean DETECT_SPICE_PARAMS = true; private static final boolean USE_JAVA_CODE = true; /** key of Variable holding generic Spice templates. */ public static final Variable.Key SPICE_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template"); /** key of Variable holding Spice 2 templates. */ public static final Variable.Key SPICE_2_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_spice2"); /** key of Variable holding Spice 3 templates. */ public static final Variable.Key SPICE_3_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_spice3"); /** key of Variable holding HSpice templates. */ public static final Variable.Key SPICE_H_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_hspice"); /** key of Variable holding PSpice templates. */ public static final Variable.Key SPICE_P_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_pspice"); /** key of Variable holding GnuCap templates. */ public static final Variable.Key SPICE_GC_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_gnucap"); /** key of Variable holding Smart Spice templates. */ public static final Variable.Key SPICE_SM_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_smartspice"); /** key of Variable holding Smart Spice templates. */ public static final Variable.Key SPICE_A_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_assura"); /** key of Variable holding Smart Spice templates. */ public static final Variable.Key SPICE_C_TEMPLATE_KEY = Variable.newKey("ATTR_SPICE_template_calibre"); /** key of Variable holding Spice model file. */ public static final Variable.Key SPICE_NETLIST_FILE_KEY = Variable.newKey("ATTR_SPICE_netlist_file"); /** key of Variable holding SPICE code. */ public static final Variable.Key SPICE_CARD_KEY = Variable.newKey("SIM_spice_card"); /** key of Variable holding SPICE declaration. */ public static final Variable.Key SPICE_DECLARATION_KEY = Variable.newKey("SIM_spice_declaration"); /** key of Variable holding SPICE model. */ public static final Variable.Key SPICE_MODEL_KEY = Variable.newKey("SIM_spice_model"); /** key of Variable holding SPICE flat code. */ public static final Variable.Key SPICE_CODE_FLAT_KEY = Variable.newKey("SIM_spice_code_flat"); /** key of Variable holding generic CDL templates. */ public static final Variable.Key CDL_TEMPLATE_KEY = Variable.newKey("ATTR_CDL_template"); /** Prefix for spice extension. */ public static final String SPICE_EXTENSION_PREFIX = "Extension "; /** Prefix for spice null extension. */ public static final String SPICE_NOEXTENSION_PREFIX = "N O N E "; /** maximum subcircuit name length */ private static final int SPICEMAXLENSUBCKTNAME = 70; /** maximum subcircuit name length */ private static final int CDLMAXLENSUBCKTNAME = 40; /** maximum subcircuit name length */ private static final int SPICEMAXLENLINE = 78; /** legal characters in a spice deck */ private static final String SPICELEGALCHARS = "!#$%*+-/<>[]_@"; /** legal characters in a spice deck */ private static final String PSPICELEGALCHARS = "!#$%*+-/<>[]_"; /** legal characters in a CDL deck */ private static final String CDLNOBRACKETLEGALCHARS = "!#$%*+-/<>_"; /** if CDL writes out empty subckt definitions */ private static final boolean CDLWRITESEMPTYSUBCKTS = false; /** A mark for uniquify */ private static final Set<Variable.Key> UNIQUIFY_MARK = Collections.emptySet(); /** default Technology to use. */ private Technology layoutTechnology; /** Mask shrink factor (default =1) */ private double maskScale; /** True to write CDL format */ private boolean useCDL; /** Legal characters */ private String legalSpiceChars; /** Template Key for current spice engine */ private Variable.Key preferedEngineTemplateKey; /** Special case for HSpice for Assura */ private boolean assuraHSpice = false; /** Spice type: 2, 3, H, P, etc */ private Simulation.SpiceEngine spiceEngine; /** those cells that have overridden models */ private Map<Cell,String> modelOverrides = new HashMap<Cell,String>(); /** Parameters used for Spice */ private Map<NodeProto,Set<Variable.Key>> allSpiceParams = new HashMap<NodeProto,Set<Variable.Key>>(); /** for RC parasitics */ private SpiceParasiticsGeneral parasiticInfo; /** Networks exempted during parasitic ext */ private SpiceExemptedNets exemptedNets; /** Whether or not to write empty subckts */ private boolean writeEmptySubckts = true; /** max length per line */ private int spiceMaxLenLine = SPICEMAXLENLINE; /** Flat measurements file */ private FlatSpiceCodeVisitor spiceCodeFlat = null; /** map of "parameterized" cells not covered by Topology */ private Map<Cell,Cell> uniquifyCells; /** uniqueID */ private int uniqueID; /** map of shortened instance names */ private Map<String,Integer> uniqueNames; /** * Constructor for the Spice netlister. */ Spice() {} /** * The main entry point for Spice deck writing. * @param cell the top-level cell to write. * @param context the hierarchical context to the cell. * @param filePath the disk file to create. * @param cdl true if this is CDL output (false for Spice). */ public static void writeSpiceFile(Cell cell, VarContext context, String filePath, boolean cdl) { Spice out = new Spice(); out.useCDL = cdl; if (out.openTextOutputStream(filePath)) return; if (out.writeCell(cell, context)) return; if (out.closeTextOutputStream()) return; System.out.println(filePath + " written"); // write CDL support file if requested if (out.useCDL) { // write the control files String deckFile = filePath; String deckPath = ""; int lastDirSep = deckFile.lastIndexOf(File.separatorChar); if (lastDirSep > 0) { deckPath = deckFile.substring(0, lastDirSep); deckFile = deckFile.substring(lastDirSep+1); } String templateFile = deckPath + File.separator + cell.getName() + ".cdltemplate"; if (out.openTextOutputStream(templateFile)) return; String libName = Simulation.getCDLLibName(); String libPath = Simulation.getCDLLibPath(); out.printWriter.print("cdlInKeys = list(nil\n"); out.printWriter.print(" 'searchPath \"" + deckFile + ""); if (libPath.length() > 0) out.printWriter.print("\n " + libPath); out.printWriter.print("\"\n"); out.printWriter.print(" 'cdlFile \"" + deckPath + File.separator + deckFile + "\"\n"); out.printWriter.print(" 'userSkillFile \"\"\n"); out.printWriter.print(" 'opusLib \"" + libName + "\"\n"); out.printWriter.print(" 'primaryCell \"" + cell.getName() + "\"\n"); out.printWriter.print(" 'caseSensitivity \"lower\"\n"); out.printWriter.print(" 'hierarchy \"flatten\"\n"); out.printWriter.print(" 'cellTable \"\"\n"); out.printWriter.print(" 'viewName \"netlist\"\n"); out.printWriter.print(" 'viewType \"\"\n"); out.printWriter.print(" 'pr nil\n"); out.printWriter.print(" 'skipDevice nil\n"); out.printWriter.print(" 'schemaLib \"sample\"\n"); out.printWriter.print(" 'refLib \"\"\n"); out.printWriter.print(" 'globalNodeExpand \"full\"\n"); out.printWriter.print(")\n"); if (out.closeTextOutputStream()) return; System.out.println(templateFile + " written"); } String runSpice = Simulation.getSpiceRunChoice(); if (!runSpice.equals(Simulation.spiceRunChoiceDontRun)) { String command = Simulation.getSpiceRunProgram() + " " + Simulation.getSpiceRunProgramArgs(); // see if user specified custom dir to run process in String workdir = User.getWorkingDirectory(); String rundir = workdir; if (Simulation.getSpiceUseRunDir()) { rundir = Simulation.getSpiceRunDir(); } File dir = new File(rundir); int start = filePath.lastIndexOf(File.separator); if (start == -1) start = 0; else { start++; if (start > filePath.length()) start = filePath.length(); } int end = filePath.lastIndexOf("."); if (end == -1) end = filePath.length(); String filename_noext = filePath.substring(start, end); String filename = filePath.substring(start, filePath.length()); // replace vars in command and args command = command.replaceAll("\\$\\{WORKING_DIR}", workdir); command = command.replaceAll("\\$\\{USE_DIR}", rundir); command = command.replaceAll("\\$\\{FILENAME}", filename); command = command.replaceAll("\\$\\{FILENAME_NO_EXT}", filename_noext); // set up run probe FileType type = Simulate.getCurrentSpiceOutputType(); String [] extensions = type.getExtensions(); String outFile = rundir + File.separator + filename_noext + "." + extensions[0]; Exec.FinishedListener l = new SpiceFinishedListener(cell, type, outFile); if (runSpice.equals(Simulation.spiceRunChoiceRunIgnoreOutput)) { Exec e = new Exec(command, null, dir, null, null); if (Simulation.getSpiceRunProbe()) e.addFinishedListener(l); e.start(); } if (runSpice.equals(Simulation.spiceRunChoiceRunReportOutput)) { ExecDialog dialog = new ExecDialog(TopLevel.getCurrentJFrame(), false); if (Simulation.getSpiceRunProbe()) dialog.addFinishedListener(l); dialog.startProcess(command, null, dir); } System.out.println("Running spice command: "+command); } if (Simulation.isParasiticsBackAnnotateLayout() && out.parasiticInfo != null) { out.parasiticInfo.backAnnotate(); } } /** * Method called once by the traversal mechanism. * Initializes Spice netlisting and writes headers. */ protected void start() { // find the proper technology to use if this is schematics if (topCell.getTechnology().isLayout()) layoutTechnology = topCell.getTechnology(); else layoutTechnology = Schematics.getDefaultSchematicTechnology(); // make sure key is cached spiceEngine = Simulation.getSpiceEngine(); preferedEngineTemplateKey = SPICE_TEMPLATE_KEY; assuraHSpice = false; switch (spiceEngine) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -