A VUnit package making Python callable from VHDL.
vunit-python-bridge embeds a Python interpreter in the simulator process so that a VHDL testbench
can execute Python code and call Python functions — a NumPy reference model, a constraint solver, a
plot of what the design just produced — without leaving the simulation. The VHDL API,
python_pkg/python_context, is compiled into the python_bridge library and is implemented for
the selected simulator by a foreign language interface the package builds itself: a small C library
called through VHPIDIRECT (NVC, GHDL) or the FLI (Questa/ModelSim), or a VHPI application built with
the simulator's own compiler driver (Riviera-PRO/Active-HDL). Values cross the interface with their
VHDL types: integer, real, string, boolean, std_ulogic, unsigned/signed, the vector
types, and integer_array_t as a NumPy array.
pip install vunit-python-bridgeThe run script adds the package after the VUnit builtins:
from vunit import VUnit
vu = VUnit.from_argv()
vu.add_vhdl_builtins()
vu.add_package("vunit-python-bridge", allow_setup=True)
lib = vu.add_library("lib")
lib.add_source_files("*.vhd")
vu.main()allow_setup=True is required because, when added, the package builds its native library and
registers simulator options as part of its setup function, which VUnit only runs when the project
allows it.
The testbench gets the API from the python_context context of the python_bridge library:
library vunit_lib;
context vunit_lib.vunit_context;
library python_bridge;
context python_bridge.python_context;
...
exec("import numpy as np");
exec("def gain(x): return [2 * v for v in x]");
check_equal(eval_integer("int(np.sum([1, 2, 3]))"), 6);
check_equal(eval_string("'-'.join(['a', 'b'])"), string'("a-b"));
check(call_integer_vector("gain", arg(integer_vector'(1, 2))) = integer_vector'(2, 4));| Simulator | Interface | Status |
|---|---|---|
| NVC | VHPIDIRECT | Tested on Linux, macOS and Windows |
| GHDL (mcode, llvm-jit, llvm, gcc) | VHPIDIRECT | Tested on Linux, macOS and Windows |
| Questa/ModelSim | FLI | Tested manually on Linux; the Windows build is untested |
| Riviera-PRO, Active-HDL | VHPI | Untested; a subset of the API, see the documentation |
- VUnit 5.0.0.dev12 or later (
vunit_hdlon PyPI), which pip installs with the package. - VHDL-2008 or later.
- CPython 3.10 or later, standard (GIL) build, with a shared
libpython(--enable-shared), which is what distribution Pythons,actions/setup-python,uvandpyenvprovide by default. - Linux and macOS: a C compiler (
cc,gccorclang, orCC) and the Python development headers (for example thepython3-devpackage). The bridge library is compiled on first use and cached. - Windows: a 64-bit CPython from python.org (or compatible). The package ships prebuilt DLLs
for NVC and GHDL. Questa builds its FLI library, and NVC and GHDL their library when the DLLs
are missing, with a MinGW-w64 gcc:
CC, the one bundled with the simulator, orgcconPATH. - The bridge library is built or copied to
~/.vunit-python-bridge, not to the VUnit output path.VUNIT_PYTHON_BRIDGE_LIBRARY_DIRselects another directory on every platform.
The simulator runs Python in the same environment as VUnit itself, including an active virtual environment and its installed packages.
The documentation is at vunit-python-bridge.readthedocs.io.
Mozilla Public License, v. 2.0, like VUnit. See LICENSE.