===== Porting/Converting Spice to Verilog(-AMS) ===== Verilog-AMS has been designed to coexist with Spice, and to replace it as needed (among other things). Citing from Annex E of the language reference manual, //Analog simulation has long been performed with SPICE and SPICE-like simulators. As such, there is a huge legacy of SPICE netlists.// These are supposed to retain its use when upgrading a SPICE simulator. On the other hand, Annex E provides a list of "SPICE primitives" that facilitate the rewrite of basic SPICE netlists. ==== SPICE Subsystem ==== Gnucap and Verilog-AMS offer mechanisms to include device models and circuits written for SPICE. The idea is to facilitate the transition from SPICE, motivated elsewhere. In theory, the approach corresponds to the "extern C" construct in C++, which has been widely successful. The limitations are as follows. - SPICE dialects are mutually incompatible, there is a need to pick one at least as a starting point. Supporting all of them is likely infeasible. - Verilog-AMS does not mandate a specific SPICE dialect for use in a Verilog-AMS environment. As a consequence, no two SPICE subsystems in two distinct Simulators will be compatible. This defies the purpose of standardisation. - A full transition to Verilog-AMS can be neccessary to enable an endless list of features missing in SPICE and its derivatives. If those are needed, even a manual rewrite can be more practical and less time consuming than inventing and implementing workarounds. Gnucap offers a SPICE subsystem subject to these issues. ==== Netlist translation ==== A SPICE netlist is composed of a list of device instances. What we need to do is find a substitute for each such instance. We use lower case letters only for consistency and to aid recognition after the translation. === Basic simple case === In some cases, devices can be substituted following Annex E. ^ SPICE ^ Verilog-AMS ^ | ''R1 a b 1k'' | ''resistor #(.r(1k)) r1(.p(a), .n(b));'' | | ''V1 a B sin 1 1k 1'' | ''vsine #(.ampl(1.), .freq(1k), .offset(1)) v1(.p(a), .n(b));'' | | ''C1 a b 1u ic=1.'' | ''capacitor #(.c(1u), .ic(1.) C1 (.p(a), .n(b));'' | Note that in SPICE the type is implicit, often encoded in the label. We need to find the correct type, and simply keep the label. The port and parameter assignments depend on the SPICE dialect used in the legacy netlist. A translation to Verilog will hence make a guess and assign names accordingly. Both a wrong guess, or an error in the SPICE netlist will be easy to spot after the translation. vsine #(.freq(1.), .ampl(1k), .offset(1)) V1(.p(a), .n(b)); It remains to check if additional parameters in a desired SPICE device instance, such as ''ic'' in a capacitor, actually match the behaviour described in table E1. === Behavioural modelling === SPICE provides modelling features between netlisting and device modelling. These need special treatment. For example a vccs like G1 a b c d dc {p} tran {p*tanh(V(c,d))} To represent "G1" in a Verilog-AMS system, we need a substitute similar to parameter real p; analog begin if($analysis("dc")) begin V(a,b) <+ p; end else if($analysis("tran")) begin V(a,b) <+ p*V(c,d); end end Such a substitute needs a module context to work, and a compiler. === Specific cases === TODO === ".model" instances === The ''.model'' statement refers to model code often hardwired in the simulator. A "model instance" defines a device prototype that somehow relates to that model code. For example .MODEL MYNPN NPN BF=80 IS=1E-18 RB=100 VAF=50 CJE=3PF CJC=2PF CJS=2PF TF=0.3NS TR=6NS Refers to an "npn" device "model" provided by the simulator and declares a "MYNPN" type, which might have instances in the netlist looking similar to Q1 a b c mynpn w=1u l=2u Translating such devices highly depends on the SPICE implementation, and may be represented by a line similar to mynpn #(.w(1u), .l(2u)) Q1 (.c(a), .b(b), .e(c)); === Generic instances === Without context, an instance translation will be impossible to guess. Consider for example ?1 a b c d e, which may translate to either c #(d, e) ?1(a, b); or d #(e) ?1(a,b,c); === ".subckt" instances === Most implementations use ''X'' to indicate a subcircuit aka module instance. If the SPICE dialect used named parameters, a generic translation seems possible. X1 a b c d e='{17.}' F=42 may translate to d #(.e(17), .f(42) X1(a, b, c); with considerable success rate. Due to case insensitivity, upper case letters must be replaced by lower case. ==== prototype declarations ==== === ".subckt" === In SPICE, the ''.subckt'' directive declares a new prototype and translates to a ''module'' declaration. The devices in it need to be replaced according to the section above. For example, the declaration .subckt a b rc .parameter r=1k .parameter c=1u R1 a b r C1 b 0 c .ends translates to module rc(a, b); electrical a, b, \0 ; inout a, b; parameter real r=1k; parameter real c=1u; ground \0 ; resistor #(.r(r)) R1(.p(a), .n(b)); capacitor #(.c(c)) C1(.p(b), .n(\0 )); endmodule. The discipline binding will be required in analog blocks making use of branches (not shown). Nodes in a SPICE subckt are usually of the "electrical" type, and better choices are possible, but must be left to the user. Similarly, it is safe yet possibly suboptimal to declare ports as "inout". It is harder to automate better guesses based on the SPICE input only. Note that "0" is not a valid identifier in Verilog, and needs escaping. The node named "0" is no longer tied to ground implicitly and needs special attention. Other SPICE specific rules may apply depending on the dialect and context. === ".model" declaration === Paramset offers a virtually literal translation of a .model declaration, but requires background knowlege about the intended SPICE implementation. A line like .MODEL MYNPN NPN BF=80 IS=1E-18 could become paramset mynpn npn; .parameter real w=1u; .parameter l=1u; .w=w; .l=l; // implicit. depends on knowledge about SPICE implementation .bf=80; .is=1e-18; endparamset If "npn" is available and provides the desired device prototype. In some cases it may be more useful to implement a ''mynpn'' from scratch. A wrapper may be used to encapsulate the .model declaration and serve as a band aid for a fully fledged paramset, as follows, .subckt mynpn a b c .parameter w=1u .parameter l=1u .model mynpn_ npn bf=80 is=1E-18 q1 a b c mynpn_ w=1u l=2u .ends In Gnucap, such a wrapper may refer to the model code originally used by the SPICE netlist author.