vunit-python-bridge 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. vunit_python_bridge/__init__.py +92 -0
  2. vunit_python_bridge/bin/vunit_python_bridge-cp310-win_amd64.dll +0 -0
  3. vunit_python_bridge/bin/vunit_python_bridge-cp311-win_amd64.dll +0 -0
  4. vunit_python_bridge/bin/vunit_python_bridge-cp312-win_amd64.dll +0 -0
  5. vunit_python_bridge/bin/vunit_python_bridge-cp313-win_amd64.dll +0 -0
  6. vunit_python_bridge/bin/vunit_python_bridge-cp314-win_amd64.dll +0 -0
  7. vunit_python_bridge/bridge.py +171 -0
  8. vunit_python_bridge/foreign_application.py +90 -0
  9. vunit_python_bridge/hdl/src/python_bridge_pkg.vhd.in +91 -0
  10. vunit_python_bridge/hdl/src/python_context.vhd +13 -0
  11. vunit_python_bridge/hdl/src/python_ffi_pkg_bridge.vhd +507 -0
  12. vunit_python_bridge/hdl/src/python_pkg.vhd +1087 -0
  13. vunit_python_bridge/hdl/src/python_pkg_vhpi.vhd +270 -0
  14. vunit_python_bridge/hdl/tools/generate_python_pkg.py +386 -0
  15. vunit_python_bridge/hdl/tools/python_pkg.vhd.in +765 -0
  16. vunit_python_bridge/native/arguments.c +191 -0
  17. vunit_python_bridge/native/bridge.h +117 -0
  18. vunit_python_bridge/native/config.c +201 -0
  19. vunit_python_bridge/native/error.c +120 -0
  20. vunit_python_bridge/native/fli.c +98 -0
  21. vunit_python_bridge/native/interpreter.c +271 -0
  22. vunit_python_bridge/native/operations.c +239 -0
  23. vunit_python_bridge/native/vhpi/python_pkg.c +125 -0
  24. vunit_python_bridge/native/vhpi/python_pkg.h +31 -0
  25. vunit_python_bridge/native/vhpi/python_pkg_vhpi.c +366 -0
  26. vunit_python_bridge/native_library.py +455 -0
  27. vunit_python_bridge/runtime.py +645 -0
  28. vunit_python_bridge/simulator_hooks.py +141 -0
  29. vunit_python_bridge/vunit_pkg.toml +17 -0
  30. vunit_python_bridge-0.1.0.dist-info/METADATA +116 -0
  31. vunit_python_bridge-0.1.0.dist-info/RECORD +34 -0
  32. vunit_python_bridge-0.1.0.dist-info/WHEEL +5 -0
  33. vunit_python_bridge-0.1.0.dist-info/licenses/LICENSE +373 -0
  34. vunit_python_bridge-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,141 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ #
5
+ # Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+
7
+
8
+ """
9
+ Simulator hooks making the simulator load the bridge library and its dependencies.
10
+
11
+ They are registered with the package context by the setup function of the package, one set
12
+ per simulator, and are only called for the project they were registered for.
13
+
14
+ Questa needs no help finding the library itself: the FLI attributes of the generated
15
+ python_bridge_pkg.vhd name it by absolute path.
16
+ """
17
+
18
+ import os
19
+ import subprocess
20
+ import sys
21
+ from pathlib import Path
22
+ from typing import Dict, List, Optional
23
+
24
+ from .bridge import GHDL_LINKING_BACKENDS, PythonBridge
25
+
26
+ # The vsim flag keeping the runtime libraries Questa bundles out of the dynamic library
27
+ # search path, and the help category listing every vsim flag.
28
+ NO_AUTO_LD_LIBRARY_PATH = "-noautoldlibpath"
29
+ VSIM_HELP_ARGUMENTS = ("-help", "all")
30
+
31
+
32
+ def register(context, bridge: PythonBridge) -> None:
33
+ """
34
+ Register the hooks of every simulator the bridge serves with the package context.
35
+ """
36
+ context.register_simulator_hooks("nvc", run_flags=_nvc_run_flags(bridge))
37
+ context.register_simulator_hooks(
38
+ "ghdl",
39
+ elab_flags=_ghdl_elab_flags(bridge),
40
+ run_env=_ghdl_run_env(bridge),
41
+ )
42
+ context.register_simulator_hooks("modelsim", process_flags=_modelsim_process_flags())
43
+
44
+
45
+ def _nvc_run_flags(bridge: PythonBridge):
46
+ """
47
+ NVC run (-r) flags loading the bridge.
48
+ """
49
+
50
+ def hook(simulator_interface) -> List[str]: # pylint: disable=unused-argument
51
+ return [f"--load={bridge.library_file!s}"]
52
+
53
+ return hook
54
+
55
+
56
+ def _ghdl_elab_flags(bridge: PythonBridge):
57
+ """
58
+ GHDL elaboration flags. Only the backends linking the design ahead of time need them,
59
+ the others load the bridge at run time and are served by the run environment.
60
+ """
61
+
62
+ def hook(simulator_interface) -> List[str]:
63
+ if simulator_interface.backend not in GHDL_LINKING_BACKENDS:
64
+ return []
65
+ return [f"-Wl,-L{bridge.library_file.parent!s}"]
66
+
67
+ return hook
68
+
69
+
70
+ def _ghdl_run_env(bridge: PythonBridge):
71
+ """
72
+ Add the bridge directory to the dynamic library search path of a GHDL simulation.
73
+ """
74
+
75
+ def hook(simulator_interface, env: Dict[str, str]) -> Dict[str, str]: # pylint: disable=unused-argument
76
+ variable = {"win32": "PATH", "darwin": "DYLD_LIBRARY_PATH"}.get(sys.platform, "LD_LIBRARY_PATH")
77
+ env = dict(env)
78
+ env[variable] = os.pathsep.join(
79
+ item for item in (str(bridge.library_file.parent), env.get(variable, "")) if item
80
+ )
81
+ return env
82
+
83
+ return hook
84
+
85
+
86
+ def _modelsim_process_flags():
87
+ """
88
+ Flags for the vsim process VUnit starts for a Questa/ModelSim simulation.
89
+
90
+ Questa/ModelSim puts the directory of the C++ runtime it bundles first in
91
+ LD_LIBRARY_PATH. That runtime is regularly older than the one the Python extension
92
+ modules of the environment (NumPy, used for integer_array_t values) were built
93
+ against, and they then fail to load in the embedded interpreter. -noautoldlibpath
94
+ turns that off, leaving the C++ runtime of the system to be found as usual.
95
+
96
+ The flag is set up when the process starts, so it is only honoured on the command line
97
+ of the vsim process itself, not on the vsim command of the do-file VUnit generates.
98
+
99
+ Only relevant on Linux, where LD_LIBRARY_PATH decides this, and only given to a vsim
100
+ that knows the flag.
101
+ """
102
+ known: Dict[Optional[str], bool] = {}
103
+
104
+ def hook(simulator_interface) -> List[str]:
105
+ if not sys.platform.startswith("linux"):
106
+ return []
107
+
108
+ prefix = simulator_interface.prefix
109
+ if prefix not in known:
110
+ known[prefix] = _vsim_knows_flag(prefix, simulator_interface)
111
+ if not known[prefix]:
112
+ return []
113
+
114
+ return [NO_AUTO_LD_LIBRARY_PATH]
115
+
116
+ return hook
117
+
118
+
119
+ def _vsim_knows_flag(prefix: Optional[str], simulator_interface) -> bool:
120
+ """
121
+ Whether the vsim of an installation lists -noautoldlibpath among its options.
122
+
123
+ Asking vsim rather than assuming keeps a version without the flag from failing to
124
+ start at all. An installation that cannot be asked is taken to know it, since the
125
+ flag is what makes the bridge usable there.
126
+ """
127
+ if prefix is None:
128
+ return True
129
+
130
+ try:
131
+ output = subprocess.run(
132
+ [str(Path(prefix) / "vsim"), *VSIM_HELP_ARGUMENTS],
133
+ check=True,
134
+ capture_output=True,
135
+ text=True,
136
+ env=simulator_interface.get_env(),
137
+ ).stdout
138
+ except (OSError, subprocess.SubprocessError):
139
+ return True
140
+
141
+ return NO_AUTO_LD_LIBRARY_PATH in output.split()
@@ -0,0 +1,17 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ #
5
+ # Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+
7
+ [package]
8
+ # The VUnit adding packages and simulator hooks, VUnit/vunit#1221
9
+ requires-vunit = ">=5.0.0.dev12"
10
+ requires-vhdl = ">=2008"
11
+ library = "python_bridge"
12
+ setup = "vunit_python_bridge:setup"
13
+
14
+ # The foreign language interface implementing python_ffi_pkg is selected by the
15
+ # setup function since the choice depends on the simulator.
16
+ [[package.sources]]
17
+ include = ["hdl/src/python_context.vhd", "hdl/src/python_pkg.vhd"]
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: vunit-python-bridge
3
+ Version: 0.1.0
4
+ Summary: A VUnit package making Python callable from VHDL.
5
+ Author-email: Lars Asplund <lars.anders.asplund@gmail.com>
6
+ License-Expression: MPL-2.0
7
+ Project-URL: homepage, https://github.com/VUnit/vunit-python-bridge
8
+ Keywords: vunit,vunitpkg,verification,vhdl,fpga,asic,python,vhpi,vhpidirect,fli
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
11
+ Classifier: Natural Language :: English
12
+ Classifier: Intended Audience :: Developers
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: numpy
17
+ Requires-Dist: vunit_hdl>=5.0.0.dev12
18
+ Dynamic: license-file
19
+
20
+ # vunit-python-bridge
21
+
22
+ A VUnit package making Python callable from VHDL.
23
+
24
+ ## Overview
25
+
26
+ vunit-python-bridge embeds a Python interpreter in the simulator process so that a VHDL testbench
27
+ can execute Python code and call Python functions — a NumPy reference model, a constraint solver, a
28
+ plot of what the design just produced — without leaving the simulation. The VHDL API,
29
+ `python_pkg`/`python_context`, is compiled into the `python_bridge` library and is implemented for
30
+ the selected simulator by a foreign language interface the package builds itself: a small C library
31
+ called through VHPIDIRECT (NVC, GHDL) or the FLI (Questa/ModelSim), or a VHPI application built with
32
+ the simulator's own compiler driver (Riviera-PRO/Active-HDL). Values cross the interface with their
33
+ VHDL types: `integer`, `real`, `string`, `boolean`, `std_ulogic`, `unsigned`/`signed`, the vector
34
+ types, and `integer_array_t` as a NumPy array.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install vunit-python-bridge
40
+ ```
41
+
42
+ ## Basic Example
43
+
44
+ The run script adds the package after the VUnit builtins:
45
+
46
+ ```python
47
+ from vunit import VUnit
48
+
49
+ vu = VUnit.from_argv()
50
+ vu.add_vhdl_builtins()
51
+ vu.add_package("vunit-python-bridge", allow_setup=True)
52
+
53
+ lib = vu.add_library("lib")
54
+ lib.add_source_files("*.vhd")
55
+
56
+ vu.main()
57
+ ```
58
+
59
+ `allow_setup=True` is required because, when added, the package builds its native library and
60
+ registers simulator options as part of its setup function, which VUnit only runs when the project
61
+ allows it.
62
+
63
+ The testbench gets the API from the `python_context` context of the `python_bridge` library:
64
+
65
+ ```vhdl
66
+ library vunit_lib;
67
+ context vunit_lib.vunit_context;
68
+
69
+ library python_bridge;
70
+ context python_bridge.python_context;
71
+
72
+ ...
73
+
74
+ exec("import numpy as np");
75
+ exec("def gain(x): return [2 * v for v in x]");
76
+
77
+ check_equal(eval_integer("int(np.sum([1, 2, 3]))"), 6);
78
+ check_equal(eval_string("'-'.join(['a', 'b'])"), string'("a-b"));
79
+ check(call_integer_vector("gain", arg(integer_vector'(1, 2))) = integer_vector'(2, 4));
80
+ ```
81
+
82
+ ## Supported Simulators
83
+
84
+ | Simulator | Interface | Status |
85
+ | --- | --- | --- |
86
+ | NVC | VHPIDIRECT | Tested on Linux, macOS and Windows |
87
+ | GHDL (mcode, llvm-jit, llvm, gcc) | VHPIDIRECT | Tested on Linux, macOS and Windows |
88
+ | Questa/ModelSim | FLI | Tested manually on Linux; the Windows build is untested |
89
+ | Riviera-PRO, Active-HDL | VHPI | Untested; a subset of the API, see the documentation |
90
+
91
+ ## Requirements
92
+
93
+ - VUnit 5.0.0.dev12 or later (`vunit_hdl` on PyPI), which pip installs with the package.
94
+ - VHDL-2008 or later.
95
+ - CPython 3.10 or later, standard (GIL) build, with a shared `libpython` (`--enable-shared`), which
96
+ is what distribution Pythons, `actions/setup-python`, `uv` and `pyenv` provide by default.
97
+ - Linux and macOS: a C compiler (`cc`, `gcc` or `clang`, or `CC`) and the Python development headers
98
+ (for example the `python3-dev` package). The bridge library is compiled on first use and cached
99
+ under the VUnit output path.
100
+ - Windows: a 64-bit CPython from python.org (or compatible). The package ships prebuilt DLLs
101
+ for NVC and GHDL. Questa builds its FLI library, and NVC and GHDL their library when the DLLs
102
+ are missing, with a MinGW-w64 gcc: `CC`, the one bundled with the simulator, or `gcc` on `PATH`.
103
+
104
+ The simulator runs Python in the same environment as VUnit itself, including an active virtual
105
+ environment and its installed packages.
106
+
107
+ ## Documentation
108
+
109
+ The user guide is in [docs/user_guide.rst](docs/user_guide.rst): sessions, `exec`, `eval`, `call`
110
+ and its argument forms, `exec_file`, `import_run_script`, the type mapping, `integer_array_t` and
111
+ NumPy, error reporting, and how the bridge works. A complete example covering all three simulator
112
+ families is in [examples/embedded_python](examples/embedded_python).
113
+
114
+ ## License
115
+
116
+ Mozilla Public License, v. 2.0, like VUnit. See [LICENSE](LICENSE).
@@ -0,0 +1,34 @@
1
+ vunit_python_bridge/__init__.py,sha256=wCafoKlOFCqPNqweq_KnnFvaH5vzK5yP4_DtWe8lZD0,3567
2
+ vunit_python_bridge/bridge.py,sha256=zrSRD6DdkS3OInFnCKTn68Bsgde3zPH1tgAdIxq3Aqk,6973
3
+ vunit_python_bridge/foreign_application.py,sha256=hrEjGmvwmOmSS2fEZfkxd7U5RL1n4e06g_HmqEM4_jg,4103
4
+ vunit_python_bridge/native_library.py,sha256=J648lPhKAB7g10A_Huf5OIK3mIqoJIKB9nn_Mx1bkZ0,19336
5
+ vunit_python_bridge/runtime.py,sha256=oMH6ruA2aGnYrallcf6PNzswZYCg4Y7RsVD81eqgysk,24041
6
+ vunit_python_bridge/simulator_hooks.py,sha256=1GPcsWN16n3RHAx9UhqEA9pkmXrNRbUjNNPUiUhDOV4,4875
7
+ vunit_python_bridge/vunit_pkg.toml,sha256=sFyO6kIgOIk-p0-5Y1_4DHnopDmjGRXZAnuy1W6RFwQ,696
8
+ vunit_python_bridge/bin/vunit_python_bridge-cp310-win_amd64.dll,sha256=EHaeICd6cOy9uPIPrIjHxt1tZbOnyLJH-5Ky3bWtdMg,25600
9
+ vunit_python_bridge/bin/vunit_python_bridge-cp311-win_amd64.dll,sha256=9hY0qQDgrENjjhg3WRj4iL9BOPmiv-_513f1uYEhMuY,25600
10
+ vunit_python_bridge/bin/vunit_python_bridge-cp312-win_amd64.dll,sha256=nsyzWNzFfFeNiMUHzMadI0TXMUlSyQgp1KI_NjqXseE,25600
11
+ vunit_python_bridge/bin/vunit_python_bridge-cp313-win_amd64.dll,sha256=w1jKZ2ccI0JL_CX9S9ek5x6A_3E9Pxt5eh1G37Ju3o8,25600
12
+ vunit_python_bridge/bin/vunit_python_bridge-cp314-win_amd64.dll,sha256=Pe7NHoPeH1J8vdtUftaP6WOeBQ3mHVi0QiFDEt_whE8,25600
13
+ vunit_python_bridge/hdl/src/python_bridge_pkg.vhd.in,sha256=0Nqy9w2S5PuJVEYhgoiyUi9I3n_kz12iXmCYHA8eEBM,4811
14
+ vunit_python_bridge/hdl/src/python_context.vhd,sha256=zOJoo6Wu2vrzS3TF_pY36O_a6h8iRC5f3SAKwhiKeAw,479
15
+ vunit_python_bridge/hdl/src/python_ffi_pkg_bridge.vhd,sha256=EBhhxB4dWxbI4bE3sQjcaVygiOiyrmXKHC6tjcnTmtI,19284
16
+ vunit_python_bridge/hdl/src/python_pkg.vhd,sha256=5XvCeEOnZVDPLizVdjWTpS09oioHXq5e0c7v1AaaslI,40950
17
+ vunit_python_bridge/hdl/src/python_pkg_vhpi.vhd,sha256=leTiWcaMW24_WdaFWE8FvWhJzQbcfcL2KvSQEUG47fQ,10304
18
+ vunit_python_bridge/hdl/tools/generate_python_pkg.py,sha256=PifvodL_EgkaTR_AaA-tYvu6e29oNq-F8PFuoOoz-CE,13017
19
+ vunit_python_bridge/hdl/tools/python_pkg.vhd.in,sha256=fHS5gWEorAlsrNrF7iMUQWsVlzkBbIXhOYQgLujbHSI,28528
20
+ vunit_python_bridge/native/arguments.c,sha256=Bov0RZYtUehCuf3nHyxjMX4XUU2DtQ1IqqiyrO8UYQc,5774
21
+ vunit_python_bridge/native/bridge.h,sha256=uUYU3mk6wUC-M-HdXqjsaM5_NijbCVjxFR-kxOjI3B0,4886
22
+ vunit_python_bridge/native/config.c,sha256=_nftjKmM-qYirEx6PJAij5a6Ax6y6NyfAfl4tpMzXpk,5659
23
+ vunit_python_bridge/native/error.c,sha256=ImotvdMLhJQQ-znUJoltJraBuMTB13GUfA1p6LtZplE,3366
24
+ vunit_python_bridge/native/fli.c,sha256=Half7fS8BA9X3n1jjpRAsUOoNDWEqhUT4WVfn_d-WFY,4613
25
+ vunit_python_bridge/native/interpreter.c,sha256=Ey6S6NZdCGs32G43jnOnAoS04RhSwJZoGGFGlaG0CBw,8222
26
+ vunit_python_bridge/native/operations.c,sha256=8hDC4iHcYOcy9Ijh564OKEx80eoJ7GDnlbPJX4hII1g,7271
27
+ vunit_python_bridge/native/vhpi/python_pkg.c,sha256=7HzcF2upH47PHdkVZw_gWKvmrbpg5jtQI3jPwgqDHCk,3761
28
+ vunit_python_bridge/native/vhpi/python_pkg.h,sha256=_xg-efdoRZbSn0pOlt_YexPqv2-TQOn5o8AvalJ7tjg,1210
29
+ vunit_python_bridge/native/vhpi/python_pkg_vhpi.c,sha256=jkDpH9QioH2LJE9b3FTeCZxijXNjYTG-_WGVpgh6inQ,11474
30
+ vunit_python_bridge-0.1.0.dist-info/licenses/LICENSE,sha256=Pz2eACSxkhsGfW9_iN60pgy-enjnbGTj8df8O3ebnQQ,16726
31
+ vunit_python_bridge-0.1.0.dist-info/METADATA,sha256=6xxfUs7i9vvLXswfJPp80c9z1vuyUmG_ykNWaTQrA-k,4563
32
+ vunit_python_bridge-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
33
+ vunit_python_bridge-0.1.0.dist-info/top_level.txt,sha256=abj4noIVQMKaPr2m8kPPxH6RSYadeXKc0Ho2uilmlEg,20
34
+ vunit_python_bridge-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+