This shows you the differences between two versions of the page.
— |
gnucap:manual:tech:verilog2spice [2025/09/02 06:50] (current) felixs created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== 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. | ||
+ | |||
+ | <code> | ||
+ | mytype #(.myparameter(42)) mylabel(.someport(a), .otherport(b)); | ||
+ | </code> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <code> | ||
+ | (* some_spice="R${label} ${port[someport]} ${port[otherport]} ${par[value]} *) | ||
+ | mytype #(.value(42)) mydevice(.otherport(b), .someport(a)); | ||
+ | </code> | ||
+ | |||
+ | With this, an automatic transcription will be feasible (here, targetting "some_spice"), and result in | ||
+ | |||
+ | <code>Rmydevice b a 42</code> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <code> | ||
+ | mytype #(.value(42)) mydevice2(.otherport(b), .someport(a)); | ||
+ | </code> | ||
+ | |||
+ | A library file (ideally provided by Spice simulator maintainers) may provide the additional mapping template withuout interference. | ||
+ | |||
+ | <code> | ||
+ | (* some_other_spice="X${label} (${port[someport]} ${port[otherport]}) value=${par[value]} *) | ||
+ | module mytype(otherport, someport); | ||
+ | parameter value=0; | ||
+ | endmodule | ||
+ | </code> | ||
+ | |||
+ | Which will instruct the exporter to represent mydevice2 as | ||
+ | |||
+ | <code> | ||
+ | Xmydevice (b a) value=42 | ||
+ | </code> | ||
+ | |||
+ | When targeting some other Spice. | ||
+ | |||
+ | ==== Examples ==== | ||
+ | |||
+ | === Resistor === | ||
+ | A resistor declaration such as | ||
+ | <code> | ||
+ | (* spice="R${label} (${port[p]} ${port[n]}) ${par[r]}" *) | ||
+ | module resistor(p, n); | ||
+ | parameter real r=1; | ||
+ | endmodule | ||
+ | </code> | ||
+ | |||
+ | should work with nearly any spice simulator. | ||
+ | |||
+ | === The net device === | ||
+ | |||
+ | A net device could be defined as follows | ||
+ | |||
+ | <code> | ||
+ | (* ngspice="R${label} (${port[a]} ${port[b]}) 0" *) | ||
+ | module net(.a(i), .b(i)); | ||
+ | endmodule | ||
+ | </code> | ||
+ | |||
+ | And instances of it will now swiftly work with ngSpice (after the export). |