This shows you the differences between two versions of the page.
|
gnucap:manual:tech:spice2verilog [2025/09/02 06:52] felixs add reference to inverse |
gnucap:manual:tech:spice2verilog [2026/03/03 02:51] (current) felixs hsp and uic |
||
|---|---|---|---|
| Line 14: | Line 14: | ||
| - 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. | - 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. | + | Gnucap offers a SPICE subsystem subject to these issues.z |
| ==== Netlist translation ==== | ==== Netlist translation ==== | ||
| Line 107: | Line 107: | ||
| === ".model" declaration === | === ".model" declaration === | ||
| - | Paramset offers a virtually literal translation of a .model declaration, but requires background knowlege about the intended SPICE implementation. | + | In Gnucap, a .model declaration may refer directly to the model originally intended by a SPICE netlist author. A line like |
| - | A line like | + | |
| - | .MODEL MYNPN NPN BF=80 IS=1E-18 | + | .MODEL mynpn NPN BF=80 IS=1E-18 |
| - | could become | + | refers to a Spice implementation. If this implementation is available, the statement will define a type ''mynpn'' for instanciation in a Verilog context, such as |
| - | paramset mynpn npn; | + | module example(); |
| - | .parameter real w=1u; | + | mynpn #(.w(1.)) m1(a, b, c, d); |
| - | .parameter l=1u; | + | [..] |
| - | .w=w; .l=l; // implicit. depends on knowledge about SPICE implementation | + | endmodule. |
| - | .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, | + | In some cases a wrapper may be useful to encapsulate the .model declaration, for example if customised port or parameter names are required. |
| .subckt mynpn a b c | .subckt mynpn a b c | ||
| .parameter w=1u | .parameter w=1u | ||
| Line 128: | Line 126: | ||
| q1 a b c mynpn_ w=1u l=2u | q1 a b c mynpn_ w=1u l=2u | ||
| .ends | .ends | ||
| - | In Gnucap, such a wrapper may refer to the model code originally used by the SPICE netlist author. | + | |
| + | If there is no intent or need to use Spice models, the ''.model'' statement can be replaced by a paramset. | ||
| + | This requires some background knowlege about the Spice model parameters, as these have to be stated explicitly. | ||
| + | |||
| + | paramset mynpn npn; | ||
| + | .parameter real w=1u; // instance parameters | ||
| + | .parameter l=1u; // all user defined. | ||
| + | .w=w; .l=l; // mirror implicit assignment from SPICE. | ||
| + | .bf=80; .is=1e-18; // "model parameters" become ordinary parameter assignments | ||
| + | endparamset, | ||
| + | |||
| + | Also, "npn" should refer to the desired device prototype, implemented in Verilog. | ||
| + | |||
| + | === Binning === | ||
| + | |||
| + | Spice may support binning for device models. Given two model statements | ||
| + | |||
| + | .model mymos.1 nmos wmin=1 wmax=2 more=42 | ||
| + | .model mymos.2 nmos wmin=2 wmax=3 more=17 | ||
| + | |||
| + | a device instance of type "mynpn" will pick the suitable model based on 'w' and infer the value of the other parameters (here: more) accordingly. | ||
| + | |||
| + | M1 d g s b mymos w=1.5 | ||
| + | M2 d g s b mymos w=2.5 | ||
| + | |||
| + | M1 will have more=42, and M2 will end up with more=17. | ||
| + | |||
| + | In Gnucap, binned models behave like ordinary models, and "bin names" from spice are ignored, so the devices may be instanticated as if there was no binning suffix. | ||
| + | |||
| + | module example_bin(); | ||
| + | mynmos #(.w(1.5)) M1(d, g, s, b); | ||
| + | mynmos #(.w(2.5)) M2(d, g, s, b); | ||
| + | endmodule; | ||
| + | |||
| + | |||
| + | Similar to shown above without binning, this may be expressed in Verilog using the paramset construct referring to a wrapper similar to the one shown above. | ||
| + | |||
| + | .subckt mymos_wrap d gate s b | ||
| + | .parameter w=1u | ||
| + | .parameter l=1u | ||
| + | .parameter more=0 | ||
| + | .model mm nmos w=w, l=l | ||
| + | m1 d gate s b mm w=w l=l more=more | ||
| + | .ends | ||
| + | |||
| + | paramset mymos mymos_wrap | ||
| + | parameter real w=0 from [1.:2.]; | ||
| + | .more=42; | ||
| + | .w=w; | ||
| + | endparamset | ||
| + | paramset mymos mymos_wrap | ||
| + | parameter real w=0 from [2.:3.]; | ||
| + | .more=17; | ||
| + | .w=w; | ||
| + | endparamset | ||
| + | |||
| + | |||
| + | With these, M1 and M2 translate to | ||
| + | |||
| + | mymos #(.w(1.5)) M1(d,g,s,b); | ||
| + | mymos #(.w(2.5)) M2(.d(d),.gate(g),.s(s),.b(b)); | ||
| + | |||
| + | as expected, optionally with port names inferred from mymos_wrap. Note that these paramsets are self contained and reusable specifically when moving on from Spice "model + instance" .subckt wrappers to behavioural models implemented as Verilog "module". | ||
| + | |||
| + | === Type nesting === | ||
| + | |||
| + | Verilog-AMS does not explicitly require support for nested types, and they are not mentioned in the paramset specification. Moreover module and paramset declarations are supposedly at top level. | ||
| + | There is little gain from nested types in terms of expressivity, and possibly this choice was made to just improve compatibility between implementations. However, System-Verilog supports nested types, and it would be totally natural to have them. Perhaps System-Verilog-AMS will consolidate the drift. | ||
| + | |||
| + | ==== Global Options ==== | ||
| + | |||
| + | Spice simulators provide a global set of "options" that interfere with circuit behaviour and affect models. Examples are temperature, scale, method, gmin, tolerances etc. | ||
| + | Verilog-AMS offers a place for some of these options. Gnucap implements some of it, and adds features that are still missing in the standards. | ||
| + | |||
| + | Gnucap supports Spice options through the ''.option'' command. These may be accessed from Verilog code through the ''$simparam'' function, according to the standard. | ||
| + | For example, ''$simparam("scale", 1.)'' evaluates to the value managed by the ''.option'' command. Note that this is only available in behavioural models right now (early '26). | ||
| + | |||
| + | Most options are candidates for "hierarchical system parameters" (HSP). HSPs are additional device parameters with a name starting with a dollar (''$'') character. Such parameters may not be declared, but assigned and used in a module. Unrecognised HSPs are allowed for forward and backwards compatiblilty, like attributes. Example | ||
| + | |||
| + | module bad(); | ||
| + | parameter real $mfactor = 1.; // not allowed | ||
| + | endmodule; | ||
| + | module good(); | ||
| + | parameter real m = $mfactor; // OK | ||
| + | endmodule; | ||
| + | module test(); | ||
| + | good #(.$mfactor(17.)) g1(); // OK | ||
| + | good #(.$somethingelse(42.)) g2(); // allowed (in Gnucap) | ||
| + | endmodule | ||
| + | |||
| + | Gnucap implements "inofficial" HSPs ''$temperature'', ''$dtemp'', ''$method'' (early '26) following real demand. The option ''scale'' may be covered by a ''$scale'' HSP in principle. We do not wish to encourage the use of a scaling mechanism at this point, as it normally causes problems, invites funny ideas and leads to broken promises. SI units are a good choice for physical parameters. | ||
| + | |||
| + | ==== Algorithmic Peculiarities ==== | ||
| + | |||
| + | In Spice, commands and devices sometimes accept curious arguments and parameters. Often there is no need for them, once their interaction and purpose is understood. | ||
| + | |||
| + | One example is the ''ic'' parameter that supposedly sets "initial contitions" and the ''uic'' that instructs a transient simulation command to "use" initial conditions (as opposed to compute them). Both are implemented in Gnucap for backwards compatibility and to mirror Spice. Do not use them. | ||
| + | |||
| + | The ''ic'' parameter may be assigned to (say) a capacitor instance, setting an initial charge. A nonzero value puts the device into a non-converged state, as the potential across the terminals is initially zero. In theory, a computed operating point could depend on the value specified here (if there are multiple operating points). It normally does not work like this. | ||
| + | |||
| + | The purpose of ''uic'' is to circumvent non-convergence in initial dc. There are some circuits where nonconvergence is the correct result. The ''uic'' flag just sets some values and has no basis in reality. It mostly fills in zeros, where no ''ic'' has been set explicitly, assuming convergence. | ||
| + | |||
| + | In Verilog-AMS, it is possible to model initial conditions in a physically meaningful way. Behavioural models support "initial" and "analog initial" statements to initialise variables before a simulation starts. In an analog block the call ''$analysis("ic")'' tests, if the simulator is solving for an operating point (iteratively). If it does not converge, there may be something wrong with the model. The ''uic'' flag will not fix it. | ||