93 lines
84 KiB
HTML
93 lines
84 KiB
HTML
|
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||
|
<title>VLSI SAPD Documentation</title>
|
||
|
<link href="stylesheet.css" rel="stylesheet" type="text/css">
|
||
|
</head>
|
||
|
<h1 id="pagetop" class="header">VLSI SAPD Documentation</h1>
|
||
|
<center class="header">
|
||
|
<table class="header">
|
||
|
<tr>
|
||
|
<td><a href="index.html">Presentation</a></td>
|
||
|
<td><a href="agds.html">AGDS</a></td>
|
||
|
<td><a href="cif.html">CIF</a></td>
|
||
|
<td><a href="dtr.html">DTR</a></td>
|
||
|
<td><a href="openchams.html">OPENCHAMS</a></td>
|
||
|
<td><a href="spice.html">SPICE</a></td>
|
||
|
<td><a href="contact.html">Links & Contact</a></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</center>
|
||
|
<br>
|
||
|
<hr>
|
||
|
<body>
|
||
|
<!-- Generated by Doxygen 1.8.14 -->
|
||
|
</div><!-- top -->
|
||
|
<div class="header">
|
||
|
<div class="headertitle">
|
||
|
<div class="title">SPICE Format </div> </div>
|
||
|
</div><!--header-->
|
||
|
<div class="contents">
|
||
|
<div class="textblock"><h1><a class="anchor" id="spicePres"></a>
|
||
|
Presentation</h1>
|
||
|
<p>The <b>Spice</b> format was developped at the University of California, Berkeley. This parser/driver consists in a subset of SPICE3 netlist format. (see <a href="http://en.wikipedia.org/wiki/SPICE">http://en.wikipedia.org/wiki/SPICE</a> for more informations).<br />
|
||
|
</p>
|
||
|
<h2><a class="anchor" id="spiceAutrhos"></a>
|
||
|
Author</h2>
|
||
|
<p>Damien Dupuis: damien.dupuis(at)lip6(.)fr</p>
|
||
|
<h1><a class="anchor" id="spiceDB"></a>
|
||
|
Stand alone database structure</h1>
|
||
|
<p>The database consists in several objects:</p><ul>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_spice_exception.html">SPICE::SpiceException</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_subckt.html">SPICE::Subckt</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_instance.html">SPICE::Instance</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_mosfet.html">SPICE::Mosfet</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_capacitor.html">SPICE::Capacitor</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_resistor.html">SPICE::Resistor</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_source.html">SPICE::Source</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_voltage.html">SPICE::Voltage</a></li>
|
||
|
<li><a class="el" href="class_s_p_i_c_e_1_1_current.html">SPICE::Current</a></li>
|
||
|
</ul>
|
||
|
<h2><a class="anchor" id="spiceParser"></a>
|
||
|
Using the parser</h2>
|
||
|
<p>Simply load an Spice netlist file using the static function <a class="el" href="class_s_p_i_c_e_1_1_circuit.html#aa8294fe7d9ceddb5653d08ecae3eaf36" title="creates and returns a Circuit object based on a database source file. ">SPICE::Circuit::readFromFile()</a>.</p>
|
||
|
<h2><a class="anchor" id="spiceDriver"></a>
|
||
|
Using the driver</h2>
|
||
|
<p>Using the driver is very simple, user has to create a <a class="el" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a> object and simply add others Spice objects like <a class="el" href="class_s_p_i_c_e_1_1_subckt.html">SPICE::Subckt</a> or <a class="el" href="class_s_p_i_c_e_1_1_instance.html">SPICE::Instance</a> to it. Includes, libraries and parameters can also be added to <a class="el" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a>. Finally use the SPICE::Circuit::writeToFile() method to dump the database to file.</p>
|
||
|
<h1><a class="anchor" id="spiceExamples"></a>
|
||
|
Examples</h1>
|
||
|
<p>As said is the global presentation, VLSI SAPD project provides C++ libraries and Python modules for each supported format. In this section we present simple code examples to parse and drive a SPICE file using C++ or Python. The SPICE file considered describes a simple Miller OTA: <code>OTA_miller.spi</code> </p><div class="fragment"><div class="line">* Single-ended two-stage amplifier</div><div class="line"></div><div class="line">.PARAM CC_VALUE=2.8794pF</div><div class="line">.PARAM L_VALUE=0.340e-6</div><div class="line"></div><div class="line">.SUBCKT currentMirrorPMOS d1 d2 s1 s2 param: l_val=0.0 w_val=0.0 nf_val=1 aeq_val=100e-6 temp_val=27</div><div class="line">MP3 d1 d1 s1 s1 psvt l=l_val wf={w_val/nf_val} nf=nf_val aeq=aeq_val tempsimu=temp_val</div><div class="line">MP4 d2 d1 s2 s2 psvt l=l_val wf={w_val/nf_val} nf=nf_val aeq=aeq_val tempsimu=temp_val</div><div class="line">.ENDS currentMirrorPMOS</div><div class="line"></div><div class="line">.SUBCKT diffPairNMOS d1 d2 g1 g2 s b param: l_val=0.0 w_val=0.0 nf_val=1 aeq_val=100e-6 temp_val=27</div><div class="line">MN1 d1 g1 s b nsvt l=l_val wf={w_val/nf_val} nf=nf_val aeq=aeq_val tempsimu=temp_val</div><div class="line">MN2 d2 g2 s b nsvt l=l_val wf={w_val/nf_val} nf=nf_val aeq=aeq_val tempsimu=temp_val</div><div class="line">.ENDS diffPairNMOS</div><div class="line"></div><div class="line">XCM 1 2 vdd vdd currentMirrorPMOS l_val=L_VALUE w_val=3.889618e-06 nf_val=2</div><div class="line">XDP 1 2 vim vip 3 vss diffPairNMOS l_val=L_VALUE w_val=7.683346e-07 nf_val=4</div><div class="line">MP6 vout 2 vdd vdd psvt l_val=L_VALUE w_val=3.558995e-05 nf_val=20</div><div class="line">MN5 3 4 vss vss nsvt l_val=L_VALUE w_val=2.536703e-06 nf_val=4 </div><div class="line">MN7 vout 4 vss vss nsvt l_val=L_VALUE w_val=1.069083e-05 nf_val=16</div><div class="line">MN8 4 4 vss vss nsvt l_val=L_VALUE w_val=2.536703e-06 nf_val=4 </div><div class="line"></div><div class="line">CC1 vout 2 CC_VALUE</div><div class="line"></div><div class="line">.END</div></div><!-- fragment --><p>All source codes are available in the <code>examples</code> directory.</p>
|
||
|
<h2><a class="anchor" id="spiceC"></a>
|
||
|
C++</h2>
|
||
|
<h3><a class="anchor" id="spiceParseC"></a>
|
||
|
Parser</h3>
|
||
|
<p>The following code (<code>parseSpice.cpp</code>) is an example of how to parse a SPICE file using C++ library. </p><div class="fragment"><div class="line"><span class="preprocessor">#include <cstdlib></span></div><div class="line"><span class="preprocessor">#include <iostream></span></div><div class="line"><span class="preprocessor">#include <string></span></div><div class="line"><span class="preprocessor">#include <map></span></div><div class="line"><span class="preprocessor">#include <vector></span></div><div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacestd.html">std</a>;</div><div class="line"></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Circuit.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/SpiceException.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Sources.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Subckt.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Instances.h"</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[]) {</div><div class="line"> <span class="keywordtype">string</span> file = <span class="stringliteral">""</span>;</div><div class="line"> <span class="keywordflow">if</span> (argc == 1)</div><div class="line"> file = <span class="stringliteral">"./OTA.cir"</span>;</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (argc == 2)</div><div class="line"> file = argv[1];</div><div class="line"> <span class="keywordflow">else</span> {</div><div class="line"> cerr << <span class="stringliteral">"Usage: parseSpice [filename]"</span> << endl;</div><div class="line"> exit(1);</div><div class="line"> }</div><div class="line"></div><div class="line"> <a class="code" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a>* circuit = NULL;</div><div class="line"> <span class="keywordflow">try</span> {</div><div class="line"> circuit = <a class="code" href="class_s_p_i_c_e_1_1_circuit.html#aa8294fe7d9ceddb5653d08ecae3eaf36">SPICE::Circuit::readFromFile</a>(file);</div><div class="line"> } <span class="keywordflow">catch</span> (<a class="code" href="class_s_p_i_c_e_1_1_spice_exception.html">SPICE::SpiceException</a>& e) {</div><div class="line"> cerr << e.what() << endl;</div><div class="line"> exit(48);</div><div class="line"> }</div><div class="line"></div><div class="line"><span class="comment">// if (!circuit) cerr << "circuit is NULL !!" << endl;</span></div><div class="line"> <span class="comment">// TITLE</span></div><div class="line"> cerr << <span class="stringliteral">"+ "</span> << circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ad19721dd878c04c854a72af12d785741">getTitle</a>() << endl;</div><div class="line"> <span class="comment">// INCLUDES</span></div><div class="line"> vector<string> includes = circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#a312beaf640e84589e6644820355c8ed6">getIncludes</a>();</div><div class="line"> <span class="keywordflow">if</span> (includes.size()) {</div><div class="line"> cerr << <span class="stringliteral">"| + includes"</span> << endl;</div><div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0 ; i < includes.size() ; i++)</div><div class="line"> cerr << <span class="stringliteral">"| | "</span> << includes[i] << endl;</div><div class="line"> }</div><div class="line"> <span class="comment">// LIBRARIES</span></div><di
|
||
|
Driver</h3>
|
||
|
<p>This C++ code (<code>driveSpice.cpp</code>) generates an myOTA.spi file equivalent to the included one. </p><div class="fragment"><div class="line"><span class="preprocessor">#include <string></span></div><div class="line"><span class="keyword">using namespace </span><a class="code" href="namespacestd.html">std</a>;</div><div class="line"></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Circuit.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Subckt.h"</span></div><div class="line"><span class="preprocessor">#include "vlsisapd/spice/Instances.h"</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[]) {</div><div class="line"> <a class="code" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a>* circuit = <span class="keyword">new</span> <a class="code" href="class_s_p_i_c_e_1_1_circuit.html">SPICE::Circuit</a>();</div><div class="line"> circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#a798df9ebd558e22c85eeceb5202e3123">setTitle</a>(<span class="stringliteral">"* Single-ended two-stage amplifier"</span>);</div><div class="line"></div><div class="line"> <span class="comment">// PARAMS</span></div><div class="line"> circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"CC_VALUE"</span>, <span class="stringliteral">"2.8794pF"</span>);</div><div class="line"> circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"L_VALUE"</span> , <span class="stringliteral">"0.340e-6"</span>);</div><div class="line"></div><div class="line"> <span class="comment">// SUBCKTS</span></div><div class="line"> <span class="comment">// CurrentMirror</span></div><div class="line"> <a class="code" href="class_s_p_i_c_e_1_1_subckt.html">SPICE::Subckt</a>* CM = circuit-><a class="code" href="class_s_p_i_c_e_1_1_circuit.html#a0d1352e46d4537ce1e5f651de40e91a6">addSubckt</a>(<span class="stringliteral">"currentMirrorPMOS"</span>);</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">"d1"</span>);</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">"d2"</span>);</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">"s1"</span>);</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">"s2"</span>);</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"l_val"</span> , <span class="stringliteral">"0.0"</span> );</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"w_val"</span> , <span class="stringliteral">"0.0"</span> );</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"nf_val"</span> , <span class="stringliteral">"1"</span> );</div><div class="line"> CM-><a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">"aeq_val"</span> , <span class="
|
||
|
<h2><a class="anchor" id="spicePython"></a>
|
||
|
Python</h2>
|
||
|
<h3><a class="anchor" id="spiceParsePython"></a>
|
||
|
Parser</h3>
|
||
|
<p>The following python script (<code>parseSpice.py</code>) is an example of how to parse a SPICE file using python module. </p><div class="fragment"><div class="line"><span class="keyword">import</span> sys</div><div class="line"></div><div class="line"><span class="keyword">from</span> SPICE <span class="keyword">import</span> *</div><div class="line"></div><div class="line"><span class="keyword">def </span>printContents(circuit):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"+"</span>, circuit.title</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getIncludes()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + includes"</span></div><div class="line"> <span class="keywordflow">for</span> include <span class="keywordflow">in</span> circuit.getIncludes():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| |"</span>, include</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getLibraries()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + libraries"</span></div><div class="line"> <span class="keywordflow">for</span> (lib, typ) <span class="keywordflow">in</span> circuit.getLibraries():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| |"</span>, lib, typ</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getParameters()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + parameters"</span></div><div class="line"> <span class="keywordflow">for</span> (name, value) <span class="keywordflow">in</span> circuit.getParameters().items():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| | %s=%s"</span>%(name, value)</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getOptions()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + options"</span></div><div class="line"> <span class="keywordflow">for</span> (name, value) <span class="keywordflow">in</span> circuit.getOptions().items():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| | %s=%s"</span>%(name, value)</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getSources()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + sources"</span></div><div class="line"> <span class="keywordflow">for</span> source <span class="keywordflow">in</span> circuit.getSources():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| |"</span>, source.getName(), source.getPositive(), source.getNegative(), source.getValue()</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> len(circuit.getSubckts()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| + subckts"</span></div><div class="line"> <span class="keywordflow">for</span> sub <span class="keywordflow">in</span> circuit.getSubckts():</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"| | +"</span>, sub.getName(),</div><div class="line"> <span class="keywordflow">for</span> interf <span class="keywordflow">in</span> sub.getInterfaces():</div><div class="line"> <span class="keywordflow">print</span> interf,</div><div class="line"> <span class="keywordflow">if</span> len(sub.getParameters()):</div><div class="line"> <span class="keywordflow">print</span> <span class="stringliteral">"param:&
|
||
|
Driver</h3>
|
||
|
<p>This python script (<code>driveSpice.py</code>) generates an myOTA.spi file equivalent to the included one. </p><div class="fragment"><div class="line"><span class="keyword">from</span> SPICE <span class="keyword">import</span> *</div><div class="line"></div><div class="line">circuit = <a class="code" href="class_circuit.html">Circuit</a>()</div><div class="line"></div><div class="line">circuit.title = <span class="stringliteral">'* Single-ended two-stage amplifier'</span></div><div class="line"></div><div class="line"><span class="comment"># PARAMS</span></div><div class="line">circuit.addParameter(<span class="stringliteral">"CC_VALUE"</span>, <span class="stringliteral">"2.8794pF"</span>);</div><div class="line">circuit.addParameter(<span class="stringliteral">"L_VALUE"</span> , <span class="stringliteral">"0.340e-6"</span>);</div><div class="line"></div><div class="line"><span class="comment"># SUBCKTS</span></div><div class="line"><span class="comment"># CurrentMirror</span></div><div class="line">CM = circuit.addSubckt(<span class="stringliteral">"currentMirrorPMOS"</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">"d1"</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">"d2"</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">"s1"</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">"s2"</span>);</div><div class="line">CM.addParameter(<span class="stringliteral">"l_val"</span> , <span class="stringliteral">"0.0"</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">"w_val"</span> , <span class="stringliteral">"0.0"</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">"nf_val"</span> , <span class="stringliteral">"1"</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">"aeq_val"</span> , <span class="stringliteral">"100e-6"</span>);</div><div class="line">CM.addParameter(<span class="stringliteral">"temp_val"</span>, <span class="stringliteral">"27"</span> );</div><div class="line"></div><div class="line">cmP3 = Mosfet(<span class="stringliteral">"P3"</span>, <span class="stringliteral">"d1"</span>, <span class="stringliteral">"d1"</span>, <span class="stringliteral">"s1"</span>, <span class="stringliteral">"s1"</span>, <span class="stringliteral">"psvt"</span>);</div><div class="line">cmP3.addParameter(<span class="stringliteral">"l"</span> , <span class="stringliteral">"l_val"</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">"wf"</span> , <span class="stringliteral">"{w_val/nf_val}"</span>);</div><div class="line">cmP3.addParameter(<span class="stringliteral">"nf"</span> , <span class="stringliteral">"nf_val"</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">"aeq"</span> , <span class="stringliteral">"aeq_val"</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">"tempsimu"</span>, <span class="stringliteral">"temp_val"</span> );</div><div class="line">CM.addInstance(cmP3);</div><div class="line"></div><div class="line">cmP4 = Mosfet(<span class="stringliteral">"P4"</span>, <span class="stringliteral">"d2"</span>, <span class="stringliteral">"d1"</span>, <span class="stringliteral">"s2"</span>, <span class="stringliteral">"s2"</span>, <span class="stringliteral">"psvt"</span>);</div><div class="line">cmP4.addParameter(<span class="stringliteral">"l"</span> , <span class="stringliteral">"l_val"</span> );</div><div class="line">cmP4.addParameter(<span class="s
|
||
|
</div></div><!-- contents -->
|
||
|
<br>
|
||
|
<hr>
|
||
|
<table class="footer1">
|
||
|
<tr>
|
||
|
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Thu Nov 12 2020</small></td>
|
||
|
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<table class="footer2">
|
||
|
<tr>
|
||
|
<td class="LFooter">VLSI SAPD Documentation</td>
|
||
|
<td class="RFooter"><small>Copyright © 2010 - 2020 <a href="http://www.sorbonne-universite.fr">UPMC</a> All rights reserved</small></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</body>
|
||
|
</html>
|