coriolis/vlsisapd/doc/html/spice.html

93 lines
83 KiB
HTML
Raw Normal View History

<!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.13 -->
</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 SPICE::Circuit::readFromFile().</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 &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;string&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;map&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;vector&gt;</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 &quot;vlsisapd/spice/Circuit.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/SpiceException.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/Sources.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/Subckt.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/Instances.h&quot;</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">&quot;&quot;</span>;</div><div class="line"> <span class="keywordflow">if</span> (argc == 1)</div><div class="line"> file = <span class="stringliteral">&quot;./OTA.cir&quot;</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 &lt;&lt; <span class="stringliteral">&quot;Usage: parseSpice [filename]&quot;</span> &lt;&lt; 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 = SPICE::Circuit::readFromFile(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>&amp; e) {</div><div class="line"> cerr &lt;&lt; e.what() &lt;&lt; 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 &lt;&lt; &quot;circuit is NULL !!&quot; &lt;&lt; endl;</span></div><div class="line"> <span class="comment">// TITLE</span></div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;+ &quot;</span> &lt;&lt; circuit-&gt;<a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ad19721dd878c04c854a72af12d785741">getTitle</a>() &lt;&lt; endl;</div><div class="line"> <span class="comment">// INCLUDES</span></div><div class="line"> vector&lt;string&gt; includes = circuit-&gt;<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 &lt;&lt; <span class="stringliteral">&quot;| + includes&quot;</span> &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0 ; i &lt; includes.size() ; i++)</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;| | &quot;</span> &lt;&lt; includes[i] &lt;&lt; endl;</div><div class="line"> }</div><div class="line"> <span class="comment">// LIBRARIES</span></div><div class="line"> vector&lt;pair&lt;string, string&gt; &gt; libs = circuit-&gt;<a class="code
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 &lt;string&gt;</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 &quot;vlsisapd/spice/Circuit.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/Subckt.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;vlsisapd/spice/Instances.h&quot;</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-&gt;<a class="code" href="class_s_p_i_c_e_1_1_circuit.html#a798df9ebd558e22c85eeceb5202e3123">setTitle</a>(<span class="stringliteral">&quot;* Single-ended two-stage amplifier&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">// PARAMS</span></div><div class="line"> circuit-&gt;<a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;CC_VALUE&quot;</span>, <span class="stringliteral">&quot;2.8794pF&quot;</span>);</div><div class="line"> circuit-&gt;<a class="code" href="class_s_p_i_c_e_1_1_circuit.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;L_VALUE&quot;</span> , <span class="stringliteral">&quot;0.340e-6&quot;</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-&gt;<a class="code" href="class_s_p_i_c_e_1_1_circuit.html#a0d1352e46d4537ce1e5f651de40e91a6">addSubckt</a>(<span class="stringliteral">&quot;currentMirrorPMOS&quot;</span>);</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">&quot;d1&quot;</span>);</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">&quot;d2&quot;</span>);</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">&quot;s1&quot;</span>);</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ac162264683fa3d9b3384d3e8cc291fa2">addInterface</a>(<span class="stringliteral">&quot;s2&quot;</span>);</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;l_val&quot;</span> , <span class="stringliteral">&quot;0.0&quot;</span> );</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;w_val&quot;</span> , <span class="stringliteral">&quot;0.0&quot;</span> );</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;nf_val&quot;</span> , <span class="stringliteral">&quot;1&quot;</span> );</div><div class="line"> CM-&gt;<a class="code" href="class_s_p_i_c_e_1_1_subckt.html#ab3ab147a16bc490ce96db905a4ca271c">addParameter</a>(<span class="stringliteral">&quot;aeq_val&quot;</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">&quot;+&quot;</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">&quot;| + includes&quot;</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">&quot;| |&quot;</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">&quot;| + libraries&quot;</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">&quot;| |&quot;</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">&quot;| + parameters&quot;</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">&quot;| | %s=%s&quot;</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">&quot;| + options&quot;</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">&quot;| | %s=%s&quot;</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">&quot;| + sources&quot;</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">&quot;| |&quot;</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">&quot;| + subckts&quot;</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">&quot;| | +&quot;</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">&quot;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 = Circuit()</div><div class="line"></div><div class="line">circuit.title = <span class="stringliteral">&#39;* Single-ended two-stage amplifier&#39;</span></div><div class="line"></div><div class="line"><span class="comment"># PARAMS</span></div><div class="line">circuit.addParameter(<span class="stringliteral">&quot;CC_VALUE&quot;</span>, <span class="stringliteral">&quot;2.8794pF&quot;</span>);</div><div class="line">circuit.addParameter(<span class="stringliteral">&quot;L_VALUE&quot;</span> , <span class="stringliteral">&quot;0.340e-6&quot;</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">&quot;currentMirrorPMOS&quot;</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">&quot;d1&quot;</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">&quot;d2&quot;</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">&quot;s1&quot;</span>);</div><div class="line">CM.addInterface(<span class="stringliteral">&quot;s2&quot;</span>);</div><div class="line">CM.addParameter(<span class="stringliteral">&quot;l_val&quot;</span> , <span class="stringliteral">&quot;0.0&quot;</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">&quot;w_val&quot;</span> , <span class="stringliteral">&quot;0.0&quot;</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">&quot;nf_val&quot;</span> , <span class="stringliteral">&quot;1&quot;</span> );</div><div class="line">CM.addParameter(<span class="stringliteral">&quot;aeq_val&quot;</span> , <span class="stringliteral">&quot;100e-6&quot;</span>);</div><div class="line">CM.addParameter(<span class="stringliteral">&quot;temp_val&quot;</span>, <span class="stringliteral">&quot;27&quot;</span> );</div><div class="line"></div><div class="line">cmP3 = Mosfet(<span class="stringliteral">&quot;P3&quot;</span>, <span class="stringliteral">&quot;d1&quot;</span>, <span class="stringliteral">&quot;d1&quot;</span>, <span class="stringliteral">&quot;s1&quot;</span>, <span class="stringliteral">&quot;s1&quot;</span>, <span class="stringliteral">&quot;psvt&quot;</span>);</div><div class="line">cmP3.addParameter(<span class="stringliteral">&quot;l&quot;</span> , <span class="stringliteral">&quot;l_val&quot;</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">&quot;wf&quot;</span> , <span class="stringliteral">&quot;{w_val/nf_val}&quot;</span>);</div><div class="line">cmP3.addParameter(<span class="stringliteral">&quot;nf&quot;</span> , <span class="stringliteral">&quot;nf_val&quot;</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">&quot;aeq&quot;</span> , <span class="stringliteral">&quot;aeq_val&quot;</span> );</div><div class="line">cmP3.addParameter(<span class="stringliteral">&quot;tempsimu&quot;</span>, <span class="stringliteral">&quot;temp_val&quot;</span> );</div><div class="line">CM.addInstance(cmP3);</div><div class="line"></div><div class="line">cmP4 = Mosfet(<span class="stringliteral">&quot;P4&quot;</span>, <span class="stringliteral">&quot;d2&quot;</span>, <span class="stringliteral">&quot;d1&quot;</span>, <span class="stringliteral">&quot;s2&quot;</span>, <span class="stringliteral">&quot;s2&quot;</span>, <span class="stringliteral">&quot;psvt&quot;</span>);</div><div class="line">cmP4.addParameter(<span class="stringliteral">&quot;l&quot;</span> , <span class="stringliteral">&quot;l_val&quot;</span> );</div><div class="line">cmP4.addParameter(<span class="stringliteral">&quot;wf&quot;</span> , <sp
</div></div><!-- contents -->
<br>
<hr>
<table class="footer1">
<tr>
<td class="LFooter"><small>Generated by doxygen 1.8.13 on Mon May 14 2018</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 &#169; 2010 - 2011 <a href="http://www.upmc.fr">UPMC</a> All rights reserved</small></td>
</tr>
</table>
</body>
</html>