📄 spicenetlistreader.java
字号:
String pname = defaultParName; String value = parval; if (e > 0) { pname = parval.substring(0, e); value = parval.substring(e+1); if (defaultParName != null && !defaultParName.equalsIgnoreCase(pname)) { prWarn("Expected param "+defaultParName+", but got "+pname); } } if (pname == null || value == null) { prErr("Badly formatted param=val: "+parval); return; } map.put(pname.toLowerCase(), value); } private SpiceSubckt parseSubckt(String [] parts) { SpiceSubckt subckt = new SpiceSubckt(parts[1]); int i=2; for (; i<parts.length; i++) { if (parts[i].indexOf('=') > 0) break; // parameter subckt.addPort(parts[i]); } parseParams(subckt.getParams(), i, parts); return subckt; } private SpiceInstance parseSubcktInstance(String [] parts) { String name = parts[0].substring(1); List<String> nets = new ArrayList<String>(); int i=1; for (; i<parts.length; i++) { if (parts[i].contains("=")) break; // parameter nets.add(parts[i]); } String subcktName = nets.remove(nets.size()-1); // last one is subckt reference SpiceSubckt subckt = subckts.get(subcktName.toLowerCase()); if (subckt == null) { prErr("Cannot find subckt for "+subcktName); return null; } SpiceInstance inst = new SpiceInstance(subckt, name); for (String net : nets) inst.addNet(net); parseParams(inst.getParams(), i, parts); // consistency check if (inst.getNets().size() != subckt.getPorts().size()) { prErr("Number of ports do not match: "+inst.getNets().size()+ " (instance "+name+") vs "+subckt.getPorts().size()+ " (subckt "+subckt.getName()+")"); } return inst; } private void addInstance(SpiceInstance inst) { if (inst == null) return; if (currentSubckt != null) currentSubckt.addInstance(inst); else topLevelInstances.add(inst); } private SpiceInstance parseResistor(String [] parts) { if (parts.length < 4) { prErr("Not enough arguments for resistor"); return null; } SpiceInstance inst = new SpiceInstance(parts[0]); for (int i=1; i<3; i++) { inst.addNet(parts[i]); } parseParam(inst.getParams(), parts[3], "r"); return inst; } private SpiceInstance parseCapacitor(String [] parts) { if (parts.length < 4) { prErr("Not enough arguments for capacitor"); return null; } SpiceInstance inst = new SpiceInstance(parts[0]); for (int i=1; i<3; i++) { inst.addNet(parts[i]); } parseParam(inst.getParams(), parts[3], "c"); return inst; } private SpiceInstance parseMosfet(String [] parts) { if (parts.length < 8) { prErr("Not enough arguments for mosfet"); return null; } SpiceInstance inst = new SpiceInstance(parts[0]); int i=1; for (; i<5; i++) { inst.addNet(parts[i]); } String model = parts[i]; inst.getParams().put("model", model); i++; parseParams(inst.getParams(), i, parts); return inst; } private void parseComment(String line) { if (currentSubckt == null) return; String [] parts = line.split("\\s+"); for (int i=0; i<parts.length; i++) { if (parts[i].equalsIgnoreCase("PORT") && i+2 < parts.length) { String dir = parts[i+1]; String port = parts[i+2]; SpiceSubckt.PortType type = SpiceSubckt.PortType.valueOf(dir); if (type != null) currentSubckt.setPortType(port, type); return; } } } /** * Read one line of the spice file. This concatenates continuation lines * that start with '+' to the first line, replacing '+' with ' '. It * also ignores comment lines (lines that start with '*'). * @return one spice line * @throws IOException */ private String readLine() throws IOException { while (true) { lineno++; String line = reader.readLine(); if (line == null) { // EOF if (lines.length() == 0) return null; return removeString(); } line = line.trim(); if (line.startsWith("*")) { // comment line parseComment(line); continue; } if (line.startsWith("+")) { // continuation line lines.append(" "); lines.append(line.substring(1)); continue; } // normal line if (lines.length() == 0) { // this is the first line read, read next line to see if continued lines.append(line); } else { // beginning of next line, save it and return completed line String ret = removeString(); lines.append(line); return ret; } } } private String removeString() { String ret = lines.toString(); lines.delete(0, lines.length()); return ret; } // ================================= Writing ==================================== public void writeFile(String fileName) { if (fileName == null) { write(System.out); } else { try { PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(fileName))); write(out); } catch (IOException e) { System.out.println(e.getMessage()); } } } public void write(PrintStream out) { out.println("* Spice netlist"); for (String key : options.keySet()) { String value = options.get(key); if (value == null) { out.println(".option "+key); } else { out.println(".option "+key+"="+options.get(key)); } } out.println(); for (String key : globalParams.keySet()) { out.println(".param "+key+"="+globalParams.get(key)); } out.println(); for (String net : globalNets) { out.println(".global "+net); } out.println(); for (String subcktName : subckts.keySet()) { SpiceSubckt subckt = subckts.get(subcktName); subckt.write(out); out.println(); } for (SpiceInstance inst : topLevelInstances) { inst.write(out); } out.println(); out.println(".end"); if (out != System.out) out.close(); } static void multiLinePrint(PrintStream out, boolean isComment, String str) { // put in line continuations, if over 78 chars long char contChar = '+'; if (isComment) contChar = '*'; int lastSpace = -1; int count = 0; boolean insideQuotes = false; int lineStart = 0; for (int pt = 0; pt < str.length(); pt++) { char chr = str.charAt(pt);// if (sim_spice_machine == SPICE2)// {// if (islower(*pt)) *pt = toupper(*pt);// } if (chr == '\n') { out.print(str.substring(lineStart, pt+1)); count = 0; lastSpace = -1; lineStart = pt+1; } else { if (chr == ' ' && !insideQuotes) lastSpace = pt; if (chr == '\'') insideQuotes = !insideQuotes; count++; if (count >= 78 && !insideQuotes && lastSpace > -1) { String partial = str.substring(lineStart, lastSpace+1); out.print(partial + "\n" + contChar); count = count - partial.length(); lineStart = lastSpace+1; lastSpace = -1; } } } if (lineStart < str.length()) { String partial = str.substring(lineStart); out.print(partial); } } // ======================== Spice Netlist Information ============================ // =================================== test ================================ public static void main(String [] args) { SpiceNetlistReader reader = new SpiceNetlistReader(); try { reader.readFile("/import/async/cad/2006/bic/jkg/bic/testSims/test_clk_regen.spi", true); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } reader.writeFile("/tmp/output.spi"); }// private static void testLineParserTests() {// SpiceNetlistReader reader = new SpiceNetlistReader();// reader = new SpiceNetlistReader();// reader.file = new File("/none");// reader.lineno = 1;// testLineParser(reader, ".measure tran vmin min v( data) from=0ns to=1.25ns ");// testLineParser(reader, ".param poly_res_corner='1.0 * p' * 0.8 corner");// testLineParser(reader, ".param poly_res_corner = '1.0 * p' * 0.8 corner");// testLineParser(reader, ".param AVT0N = AGAUSS(0.0, '0.01 / 0.1' , 1)");// }//// private static void testLineParser(SpiceNetlistReader reader, String line) {// System.out.println("Parsing: "+line);// String [] tokens = reader.getTokens(line);// for (int i=0; i<tokens.length; i++) {// System.out.println(i+": "+tokens[i]);// }// }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -