Skip to content

Commit 9db2cdd

Browse files
committed
Added support for GHDL.
1 parent 9718ffe commit 9db2cdd

16 files changed

+644
-212
lines changed

examples/vhdl/embedded_python/run.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
# You can obtain one at http://mozilla.org/MPL/2.0/.
44
#
5-
# Copyright (c) 2014-2023, Lars Asplund [email protected]
5+
# Copyright (c) 2014-2024, Lars Asplund [email protected]
66

77
from pathlib import Path
88
from vunit import VUnit
9-
from vunit.python_pkg import compile_vhpi_application, compile_fli_application, compile_vhpidirect_nvc_application
9+
from vunit.python_pkg import (
10+
compile_vhpi_application,
11+
compile_fli_application,
12+
compile_vhpidirect_nvc_application,
13+
compile_vhpidirect_ghdl_application,
14+
)
1015

1116

1217
def hello_world():
@@ -65,7 +70,6 @@ def main():
6570
vu.add_vhdl_builtins()
6671
vu.add_python()
6772
vu.add_random()
68-
vu.enable_location_preprocessing()
6973
simulator_name = vu.get_simulator_name()
7074

7175
if simulator_name in ["rivierapro", "activehdl"]:
@@ -76,6 +80,8 @@ def main():
7680
compile_fli_application(root, vu)
7781
elif simulator_name == "nvc":
7882
compile_vhpidirect_nvc_application(root, vu)
83+
elif simulator_name == "ghdl":
84+
compile_vhpidirect_ghdl_application(root, vu)
7985

8086
lib = vu.add_library("lib")
8187
lib.add_source_files(root / "*.vhd")

examples/vhdl/embedded_python/tb_example.vhd

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
-- You can obtain one at http://mozilla.org/MPL/2.0/.
44
--
5-
-- Copyright (c) 2014-2023, Lars Asplund [email protected]
5+
-- Copyright (c) 2014-2024, Lars Asplund [email protected]
66

77
library vunit_lib;
88
context vunit_lib.vunit_context;
@@ -51,8 +51,18 @@ begin
5151
exec("from sys import prefix");
5252
exec("from pathlib import Path");
5353
exec("old_environ = environ");
54-
exec("environ['TCL_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tcl8.6')");
55-
exec("environ['TK_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tk8.6')");
54+
exec(
55+
"if (Path(prefix) / 'lib' / 'tcl8.6').exists():" +
56+
" environ['TCL_LIBRARY'] = str(Path(prefix) / 'lib' / 'tcl8.6')" +
57+
"else:" +
58+
" environ['TCL_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tcl8.6')"
59+
);
60+
exec(
61+
"if (Path(prefix) / 'lib' / 'tk8.6').exists():" +
62+
" environ['TK_LIBRARY'] = str(Path(prefix) / 'lib' / 'tk8.6')" +
63+
"else:" +
64+
" environ['TK_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tk8.6')"
65+
);
5666
end;
5767

5868
procedure unset_tcl_installation is
@@ -209,7 +219,7 @@ begin
209219
test_input := eval("test_input"); -- test_input is a variable of integer_vector_ptr_t type
210220
check(length(test_input) >= 1);
211221
check(length(test_input) <= 100);
212-
--
222+
213223
elsif run("Test run script functions") then
214224
-- As we've seen we can define Python functions with exec (fibonacci) and we can import functions from
215225
-- Python packages. Writing large functions in exec strings is not optimal since we don't

vunit/builtins.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def _add_python(self):
219219
if not self._vhdl_standard >= VHDL.STD_2008:
220220
raise RuntimeError("Python package only supports vhdl 2008 and later")
221221

222-
python_package_supported_flis = set(["VHPI", "FLI", "VHPIDIRECT"])
222+
python_package_supported_flis = set(["VHPI", "FLI", "VHPIDIRECT_NVC", "VHPIDIRECT_GHDL"])
223223
simulator_supported_flis = self._simulator_class.supported_foreign_language_interfaces()
224224
if not python_package_supported_flis & simulator_supported_flis:
225225
raise RuntimeError(f"Python package requires support for one of {', '.join(python_package_supported_flis)}")
@@ -230,8 +230,10 @@ def _add_python(self):
230230
self._vunit_lib.add_source_files(VHDL_PATH / "python" / "src" / "python_pkg_vhpi.vhd")
231231
elif "FLI" in simulator_supported_flis:
232232
self._vunit_lib.add_source_files(VHDL_PATH / "python" / "src" / "python_pkg_fli.vhd")
233-
elif "VHPIDIRECT" in simulator_supported_flis:
234-
self._vunit_lib.add_source_files(VHDL_PATH / "python" / "src" / "python_pkg_vhpidirect.vhd")
233+
elif "VHPIDIRECT_NVC" in simulator_supported_flis:
234+
self._vunit_lib.add_source_files(VHDL_PATH / "python" / "src" / "python_pkg_vhpidirect_nvc.vhd")
235+
elif "VHPIDIRECT_GHDL" in simulator_supported_flis:
236+
self._vunit_lib.add_source_files(VHDL_PATH / "python" / "src" / "python_pkg_vhpidirect_ghdl.vhd")
235237

236238
def _add_vhdl_logging(self):
237239
"""

vunit/python_pkg.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
# You can obtain one at http://mozilla.org/MPL/2.0/.
44
#
5-
# Copyright (c) 2014-2023, Lars Asplund [email protected]
5+
# Copyright (c) 2014-2024, Lars Asplund [email protected]
66

77
"""
88
Temporary helper module to compile C-code used by python_pkg.
@@ -212,3 +212,59 @@ def compile_vhpidirect_nvc_application(run_script_root, vu):
212212
print(proc.stdout)
213213
print(proc.stderr)
214214
raise RuntimeError("Failed to link NVC VHPIDIRECT application")
215+
216+
217+
def compile_vhpidirect_ghdl_application(run_script_root, vu): # pylint: disable=unused-argument
218+
"""
219+
Compile VHPIDIRECT application for GHDL.
220+
"""
221+
# TODO: Avoid putting in root # pylint: disable=fixme
222+
path_to_shared_lib = (run_script_root).resolve()
223+
if not path_to_shared_lib.exists():
224+
path_to_shared_lib.mkdir(parents=True, exist_ok=True)
225+
shared_lib = path_to_shared_lib / "python.so"
226+
path_to_python_include = (
227+
Path(sys.executable).parent.parent.resolve() / "include" / f"python{sys.version_info[0]}.{sys.version_info[1]}"
228+
)
229+
path_to_python_libs = Path(sys.executable).parent.parent.resolve() / "bin"
230+
python_shared_lib = f"libpython{sys.version_info[0]}.{sys.version_info[1]}"
231+
path_to_python_pkg = Path(__file__).parent.resolve() / "vhdl" / "python" / "src"
232+
233+
c_file_names = ["python_pkg_vhpidirect_ghdl.c", "python_pkg.c"]
234+
235+
for c_file_name in c_file_names:
236+
args = [
237+
"gcc",
238+
"-c",
239+
"-I",
240+
str(path_to_python_include),
241+
str(path_to_python_pkg / c_file_name),
242+
"-o",
243+
str(path_to_shared_lib / (c_file_name[:-1] + "o")),
244+
]
245+
246+
proc = subprocess.run(args, capture_output=True, text=True, check=False, cwd=str(path_to_shared_lib / ".."))
247+
if proc.returncode != 0:
248+
print(proc.stdout)
249+
print(proc.stderr)
250+
raise RuntimeError("Failed to compile GHDL VHPIDIRECT application")
251+
252+
args = [
253+
"gcc",
254+
"-shared",
255+
"-fPIC",
256+
"-o",
257+
str(shared_lib),
258+
str(path_to_shared_lib / "python_pkg.o"),
259+
str(path_to_shared_lib / "python_pkg_vhpidirect_ghdl.o"),
260+
"-l",
261+
python_shared_lib,
262+
"-L",
263+
str(path_to_python_libs),
264+
]
265+
266+
proc = subprocess.run(args, capture_output=True, text=True, check=False, cwd=str(path_to_shared_lib / ".."))
267+
if proc.returncode != 0:
268+
print(proc.stdout)
269+
print(proc.stderr)
270+
raise RuntimeError("Failed to link GHDL VHPIDIRECT application")

vunit/sim_if/ghdl.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ def supports_vhdl_package_generics(cls):
177177
"""
178178
return True
179179

180+
@classmethod
181+
def supported_foreign_language_interfaces(cls):
182+
"""
183+
Returns set of supported foreign interfaces
184+
"""
185+
return set(["VHPIDIRECT_GHDL"])
186+
180187
@classmethod
181188
def supports_vhpi(cls):
182189
"""

vunit/sim_if/nvc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def supported_foreign_language_interfaces(cls):
149149
"""
150150
Returns set of supported foreign interfaces
151151
"""
152-
return set(["VHPIDIRECT"])
152+
return set(["VHPIDIRECT_NVC"])
153153

154154
def setup_library_mapping(self, project):
155155
"""

vunit/vhdl/python/run.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
# You can obtain one at http://mozilla.org/MPL/2.0/.
44
#
5-
# Copyright (c) 2014-2023, Lars Asplund [email protected]
5+
# Copyright (c) 2014-2024, Lars Asplund [email protected]
66

7+
import sys
8+
from os import environ
79
from pathlib import Path
810
from vunit import VUnit
9-
from vunit.python_pkg import compile_vhpi_application, compile_fli_application, compile_vhpidirect_nvc_application
11+
from vunit.python_pkg import (
12+
compile_vhpi_application,
13+
compile_fli_application,
14+
compile_vhpidirect_nvc_application,
15+
compile_vhpidirect_ghdl_application,
16+
)
1017

1118

1219
def remote_test():
@@ -15,7 +22,6 @@ def remote_test():
1522

1623
def main():
1724
root = Path(__file__).parent
18-
1925
vu = VUnit.from_argv()
2026
vu.add_vhdl_builtins()
2127
vu.add_python()
@@ -29,6 +35,8 @@ def main():
2935
compile_fli_application(root, vu)
3036
elif simulator_name == "nvc":
3137
compile_vhpidirect_nvc_application(root, vu)
38+
elif simulator_name == "ghdl":
39+
compile_vhpidirect_ghdl_application(root, vu)
3240

3341
lib = vu.add_library("lib")
3442
lib.add_source_files(root / "test" / "*.vhd")

vunit/vhdl/python/src/python_context.vhd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
55
-- You can obtain one at http://mozilla.org/MPL/2.0/.
66
--
7-
-- Copyright (c) 2014-2023, Lars Asplund [email protected]
7+
-- Copyright (c) 2014-2024, Lars Asplund [email protected]
88

99
context python_context is
1010
library vunit_lib;

vunit/vhdl/python/src/python_pkg.vhd

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
55
-- You can obtain one at http://mozilla.org/MPL/2.0/.
66
--
7-
-- Copyright (c) 2014-2023, Lars Asplund [email protected]
7+
-- Copyright (c) 2014-2024, Lars Asplund [email protected]
88

99
use work.python_ffi_pkg.all;
1010
use work.path.all;
@@ -49,11 +49,6 @@ package python_pkg is
4949
end package;
5050

5151
package body python_pkg is
52-
function ssin (v : real) return real is
53-
begin
54-
assert false severity failure;
55-
end;
56-
5752
-- @formatter:off
5853
procedure import_module_from_file(module_path, as_module_name : string) is
5954
constant spec_name : string := "__" & as_module_name & "_spec";
@@ -64,7 +59,7 @@ package body python_pkg is
6459
spec_name & " = spec_from_file_location('" & as_module_name & "', str(Path('" & module_path & "')))" & LF &
6560
as_module_name & " = module_from_spec(" & spec_name & ")" & LF &
6661
"sys.modules['" & as_module_name & "'] = " & as_module_name & LF &
67-
spec_name & ".loader.exec_module(" & as_module_name & ")";
62+
spec_name & ".loader.exec_module(" & as_module_name & ")";
6863
begin
6964
exec(code);
7065
end;

vunit/vhdl/python/src/python_pkg_fli.vhd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
55
-- You can obtain one at http://mozilla.org/MPL/2.0/.
66
--
7-
-- Copyright (c) 2014-2023, Lars Asplund [email protected]
7+
-- Copyright (c) 2014-2024, Lars Asplund [email protected]
88

99
use std.textio.all;
1010

0 commit comments

Comments
 (0)