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). | ||