arpadbuermen/VADistiller
1
3
Fork
You've already forked VADistiller
0
Verilog-A Distiller converts SPICE3 device models from C to Verilog-A
  • Python 100%
2026年02月02日 09:00:09 +01:00
.vscode Minor fix in BSIM3. 2026年01月30日 16:20:08 +01:00
LICENSES SPDX license information added. 2025年01月30日 08:31:25 +01:00
models Updated models. 2026年02月02日 09:00:09 +01:00
vadistiller Transient flicker noise fix (TODO: BSIM3/4). 2026年01月30日 11:57:59 +01:00
.gitignore SPDX license information added. 2025年01月30日 08:31:25 +01:00
distiller.svg C code parsing. Basic AST manipulation toolkit. 2024年11月21日 12:35:36 +01:00
distiller.svg.license SPDX license information added. 2025年01月30日 08:31:25 +01:00
LICENSE Added root license file. 2026年01月28日 14:30:57 +01:00
README.md Updated readme and models. 2025年11月14日 09:56:20 +01:00
xlat.py Stopping in validator after VACASK report. 2025年11月14日 09:20:59 +01:00
xlat_bjt.py m -> _mfactor for VA models validation. 2025年11月13日 10:56:13 +01:00
xlat_bsim3v3.py Minor fix in BSIM3. 2026年01月30日 16:20:08 +01:00
xlat_bsim4v8.py Transient flicker noise fix, BSIM4. 2026年02月02日 08:35:04 +01:00
xlat_c.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_cfg.py Updated readme and models. 2025年11月14日 09:56:20 +01:00
xlat_dio.py Updated models to latest Ngspice pre master 46. 2026年01月07日 15:12:16 +01:00
xlat_jfet1.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_jfet2.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_l.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_mes1.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_mos1.py Flicker noise fix for nlev=2,3, MOS3-9. 2026年01月30日 16:00:54 +01:00
xlat_mos2.py Flicker noise fix for nlev=2,3, MOS3-9. 2026年01月30日 16:00:54 +01:00
xlat_mos3.py Flicker noise fix for nlev=2,3, MOS3-9. 2026年01月30日 16:00:54 +01:00
xlat_mos6.py Flicker noise fix for nlev=2,3, MOS3-9. 2026年01月30日 16:00:54 +01:00
xlat_mos9.py Flicker noise fix for nlev=2,3, MOS3-9. 2026年01月30日 16:00:54 +01:00
xlat_r.py opvar -> output variable 2025年11月10日 16:16:06 +01:00
xlat_vdmos.py MOSFET cleanup, updated models. 2025年11月21日 12:02:52 +01:00

distiller

Verilog-A Distiller

Verilog-A Distiller converts SPICE3 device models from C to Verilog-A. It is intended primarily for converting Ngspice device models. The generated device models can be used in Ngspice itself or in VACASK. Since the generated device models are implemented in Verilog-A they should also work in other simulators. Due to varying support for Verilog-A $limit your mileage may vary, mostly in terms of convergence.

VADistiller uses the pycparser library for parsing the C code and producing the abstract syntax tree (AST). A toolbox for manipulating C ASTs is included with VADistiller. You will also have to install gcc because VADistiller uses its preprocessor (cpp). The preprocessor must be in the system PATH.

Which models does it convert and validate?

See the models directory for the converted device models. Older device models may change/improve with newer versions of the converter.

Verilog-A device (SPICE) File Module
Linear resistor resistor.va sp_resistor
Linear capacitor capacitor.va sp_capacitor
Linear inductor inductor.va sp_inductor
Diode (levels 1 and 3) diode.va sp_diode
Gummel-Poon BJT bjt.va sp_bjt
JFET level 1 (Schichman-Hodges) jfet1.va sp_jfet1
JFET level 2 (Parker-Skellern) jfet2.va sp_jfet2
MESFET level 1 (Statz et. al.) mes1.va sp_mes1
MOSFET level 1 (Schichman-Hodges) mos1.va sp_mos1
MOSFET level 2 (Grove-Frohman) mos2.va sp_mos2
MOSFET level 3 (empirical) mos3.va sp_mos3
MOSFET level 6 (Sakurai-Newton) mos6.va sp_mos6
MOSFET level 9 (modified level 3) mos9.va sp_mos9
VDMOS vdmos.va sp_vdmos
BSIM3 3.3.0 bsim3v3.va sp_bsim3v3
BSIM4 4.8.0, 4.8.1, 4.8.2, 4.8.3 bsim4v8.va sp_bsim4v8

Obtaining Ngspice sources

VADistiller works best on the device models in the Ngspice pre-master-46 branch. Because pre-master-46 is a fast moving target it is recommended to use a particular commit. For convenience there is a fork available at Sourceforge. The vadng-pre-46 branch is the one to use. This branch also contains some changes needed by VADistiller-generated device models. Until these changes are accepted in mainline Ngspice use the forked repository. Type

git clone -b vadng-pre-46 https://git.code.sf.net/u/arpadbuermen/ngspice ngspice-pre-46

This creates the ngspice-pre-46 directory and downloads the sources of the vadng-pre-46 branch which is based on the pre-master-46 branch. Next, you need to configure the sources. We assume the build directory will be named build and will reside in the sources directory. Enter the sources directory and type

./autogen.sh
mkdir build
cd build
../configure --with-x --with-readline=yes --enable-osdi --disable-debug --enable-nobypass --disable-openmp

--enable-nobypass disables element bypassing so that comparison of built-in and converted device models in various Ngspice benchmarks will be fair. OpenMP needs to be disabled (--disable-openmp) because it is used by all OSDI devices to parallelize instance evaluation. For small devices that evaluate quickly this actually slows down the simulation significantly due to OpenMP's overhead.

If you want to validate the converted device models you will need Ngspice pre-46 or newer. Therefore build it

make

and install it to /usr/local

sudo make install

Make sure /usr/local/bin is in the PATH.

Model variants

Under certain circumstances OpenVAF creates additional internal nodes during Verilog-A model compilation. Because these nodes make the system of equations larger and thus slower to solve it is of advantage to avoid the creation of internal nodes whenever possible.

Extra internal nodes are created in two cases:

  • If a device exposes output variables (also referred to as opvars in OpenVAF) that cannot be computed directly from the solution vector (e.g. reactive currents).
  • If the computation of a noise power spectral density (usually shot or flicker noise) is based on a reactive current.

The former case is avoided by not exposing certain output variables. The latter one, however, can be avoided only if a simplified noise model is used (i.e. one that uses DC currents for computing the power spectral density). This makes the noise model usable only in ordinary small-signal noise analysis.

Due to this several variants of each model are generated.

  • default variant does not expose output variables that add internal nodes and uses the full noise model
  • sn variant does not expose output variables that add internal nodes and uses the simplified noise model
  • full variant exposes all output variables and uses the full noise model

If the sn or the full variant of a model do not differ from the default variant they are not generated. E.g. the resistor model does not have output variables that would add extra internal nodes and its noise model is not based on a reactive current so the sn and the full variants are not generated.

The default variant is stored in the models directory while the sn and the full variants can be found in the models/sn and models/full directories, respectively.

Certain models need workarounds when used with Ngspice (e.g. BSIM4). If you intend to use a Verilog-A model generated by VADistiller with Ngspice compile it with the __NGSPICE__ macro defined (i.e. add -D__NGSPICE__ to the OpenVAF command line). This will enable all workarounds needed by Ngspice.

Running the conversion

Before running the conversion edit the configuration in xlat_cfg.py. The following settings in the config variable should be verified and possibly altered:

  • sources .. the path where the Ngspice sources are located,
  • fake_libc .. the path where the pycparser's fake libc is located.

Also check the validation variable and edit the following settings:

  • compiler .. path to the OpenVAF-reloaded compiler,
  • vacask.. path to the VACASK simulator, will replace $(VACASK) in command lines run by the validator.
  • ngspice .. path to the Ngspice simulator, will replace $(NGSPICE) in command lines run by the validator.

You will need OpenVAF-reloaded for compiling the device models before they get validated. You can get the binaries here. Get the latest osdi_0.4 version because VACASK does not support older versions of the OSDI API. The osdi_0.4 version of the OpenVAF-reloaded binary is named openvaf-r.

If you install VACASK a nice summary of the compiled device model will be printed after the conversion. If you don't have VACASK the device model summary will not be printed. You can get the latest nightly build binary packages or you can compile it from the source code.

To start the conversion run

python3 xlat.py

VADistiller will read the SPICE3 device models, parse them, process them, and then dump the Verilog-A code in the models directory. After conversion each device model will be validated. For validation you will need OpenVAF-reloaded (the osdi_0.4 version) and Ngspice (pre-46 or newer).

Loading the SPICE3 device model source code is slow. To speed up the development of VADistiller the loaded device models and converter configuration are dumped to a .pck file. The next time you run the conversion the converter object with the SPICE3 sources is loaded from the corresponding .pck file which is much faster.

Each SPICE3 device model has its own configuration file. The names of the configuration files are xlat_<model_name>.py. All configured device models are listed in the xlat_cfg.py file in the what list. The xlat.py script has the following command line syntax:

python3 xlat.py [options] [model1 model2 ...]

If no device model is specified all configured device models are converted. If you change the configuration of a device the SPICE3 source files must be reloaded. Option -f forces loading of the device model sources even if a .pck file is available. To force source file loading you can also delete the .pck file before running the conversion.

The -o option specifies which variant of the models will be generated. If omitted, all variants are generated. By specifying the -c option the device model validation step is skipped. Similarly, specifying the -v option skips the conversion step and performs only device model validation. A short help is printed if you specify the -h option. The conversion process can be interrupted after the given conversion step is finished by supplying the -s options and the step name (pre, defs, structs, params, mapping, setup, temp, load, noise, post, valprep).

The converter has been tested under Debian 13. Your mileage may vary on other systems. Usually problems arise due to GCC extensions and system include files that can differ between operating systems. To fix these problems define dummy macros in xlat_cfg.py under the defines section of the config variable.

Notes

A call to $simparam in OpenVAF-generated device models is expensive (this is a weakness of OpenVAF) so it should be used sparingly. Some $simparam values are accessed as part of device model initialization code (in devsetup.c and devtemp.c). To reduce the number of $simparam calls they should be moved to compiled device model initialization code. To allow OpenVAF to do that $siparam calls must be assigned to constants in the device models generated by VADistiller. When compiling these device models OpenVAF issues warnings that a $simparam is accessed at constant initialization (which by the way is what we want). To disable this warning --allow variant_const_simparam is added to the OpenVAF command line.

Publications mentioning Verilog-A Distiller

Acknowledgement

This project is partially funded through NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.

NLnet foundation logo NGI Zero Logo