===== Using Verilog circuits in a SPICE-only simulator =====
Some SPICE simulators do not understand Verilog syntax or semantics. A subset of the structural part of Verilog maps nicely to Spice, given a library
that maps devices to a representation that works with the targeted Spice engine.
==== The mechanism ====
A device instance has a type, a label as well as parameter and port assignments.
mytype #(.myparameter(42)) mylabel(.someport(a), .otherport(b));
There is little hope for an automatic conversion to spice, due to the irregular syntax. A string template can be used to carry a representation that a spice simulator will understand. For example (see CanEDA or KiCAD for real world spice instance templates) an instance could carry a template as follows.
(* some_spice="R${label} ${port[someport]} ${port[otherport]} ${par[value]} *)
mytype #(.value(42)) mydevice(.otherport(b), .someport(a));
With this, an automatic transcription will be feasible (here, targetting "some_spice"), and result in
Rmydevice b a 42
Note that the circuit containing mydevice is still compliant with Verilog syntax, and understood by compliant tools.
==== Decoupling metadata ====
In order to decouple circuits from simulator specifics, string templates can be moved to a device library for use in a specific (Spice) simulator.
This completely makes up for the missing Verilog support in a simulator.
Suppose a circuit contains an instance similar to the example above, but without any knowledge about Spice specifics or their variants.
mytype #(.value(42)) mydevice2(.otherport(b), .someport(a));
A library file (ideally provided by Spice simulator maintainers) may provide the additional mapping template withuout interference.
(* some_other_spice="X${label} (${port[someport]} ${port[otherport]}) value=${par[value]} *)
module mytype(otherport, someport);
parameter value=0;
endmodule
Which will instruct the exporter to represent mydevice2 as
Xmydevice (b a) value=42
When targeting some other Spice.
==== Examples ====
=== Resistor ===
A resistor declaration such as
(* spice="R${label} (${port[p]} ${port[n]}) ${par[r]}" *)
module resistor(p, n);
parameter real r=1;
endmodule
should work with nearly any spice simulator.
=== The net device ===
A net device could be defined as follows
(* ngspice="R${label} (${port[a]} ${port[b]}) 0" *)
module net(.a(i), .b(i));
endmodule
And instances of it will now swiftly work with ngSpice (after the export).