Skip to content

Commit

Permalink
Added support for GHDL.
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsAsplund committed Apr 1, 2024
1 parent 9718ffe commit 25dcd0e
Show file tree
Hide file tree
Showing 13 changed files with 635 additions and 202 deletions.
10 changes: 8 additions & 2 deletions examples/vhdl/embedded_python/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

from pathlib import Path
from vunit import VUnit
from vunit.python_pkg import compile_vhpi_application, compile_fli_application, compile_vhpidirect_nvc_application
from vunit.python_pkg import (
compile_vhpi_application,
compile_fli_application,
compile_vhpidirect_nvc_application,
compile_vhpidirect_ghdl_application,
)


def hello_world():
Expand Down Expand Up @@ -65,7 +70,6 @@ def main():
vu.add_vhdl_builtins()
vu.add_python()
vu.add_random()
vu.enable_location_preprocessing()
simulator_name = vu.get_simulator_name()

if simulator_name in ["rivierapro", "activehdl"]:
Expand All @@ -76,6 +80,8 @@ def main():
compile_fli_application(root, vu)
elif simulator_name == "nvc":
compile_vhpidirect_nvc_application(root, vu)
elif simulator_name == "ghdl":
compile_vhpidirect_ghdl_application(root, vu)

lib = vu.add_library("lib")
lib.add_source_files(root / "*.vhd")
Expand Down
16 changes: 13 additions & 3 deletions examples/vhdl/embedded_python/tb_example.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,18 @@ begin
exec("from sys import prefix");
exec("from pathlib import Path");
exec("old_environ = environ");
exec("environ['TCL_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tcl8.6')");
exec("environ['TK_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tk8.6')");
exec(
"if (Path(prefix) / 'lib' / 'tcl8.6').exists():" +
" environ['TCL_LIBRARY'] = str(Path(prefix) / 'lib' / 'tcl8.6')" +
"else:" +
" environ['TCL_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tcl8.6')"
);
exec(
"if (Path(prefix) / 'lib' / 'tk8.6').exists():" +
" environ['TK_LIBRARY'] = str(Path(prefix) / 'lib' / 'tk8.6')" +
"else:" +
" environ['TK_LIBRARY'] = str(Path(prefix) / 'tcl' / 'tk8.6')"
);
end;

procedure unset_tcl_installation is
Expand Down Expand Up @@ -209,7 +219,7 @@ begin
test_input := eval("test_input"); -- test_input is a variable of integer_vector_ptr_t type
check(length(test_input) >= 1);
check(length(test_input) <= 100);
--

elsif run("Test run script functions") then
-- As we've seen we can define Python functions with exec (fibonacci) and we can import functions from
-- Python packages. Writing large functions in exec strings is not optimal since we don't
Expand Down
8 changes: 5 additions & 3 deletions vunit/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def _add_python(self):
if not self._vhdl_standard >= VHDL.STD_2008:
raise RuntimeError("Python package only supports vhdl 2008 and later")

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

def _add_vhdl_logging(self):
"""
Expand Down
57 changes: 57 additions & 0 deletions vunit/python_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,60 @@ def compile_vhpidirect_nvc_application(run_script_root, vu):
print(proc.stdout)
print(proc.stderr)
raise RuntimeError("Failed to link NVC VHPIDIRECT application")

def compile_vhpidirect_ghdl_application(run_script_root, vu):
"""
Compile VHPIDIRECT application for GHDL.
"""
#path_to_shared_lib = (run_script_root / "vunit_out" / vu.get_simulator_name() / "libraries").resolve()
path_to_shared_lib = (run_script_root).resolve()
if not path_to_shared_lib.exists():
path_to_shared_lib.mkdir(parents=True, exist_ok=True)
shared_lib = path_to_shared_lib / "python.so"
path_to_python_include = (
Path(sys.executable).parent.parent.resolve() / "include" / f"python{sys.version_info[0]}.{sys.version_info[1]}"
)
path_to_python_libs = Path(sys.executable).parent.parent.resolve() / "bin"
python_shared_lib = f"libpython{sys.version_info[0]}.{sys.version_info[1]}"
path_to_python_pkg = Path(__file__).parent.resolve() / "vhdl" / "python" / "src"

c_file_names = ["python_pkg_vhpidirect_ghdl.c", "python_pkg.c"]

for c_file_name in c_file_names:
args = [
"gcc",
"-c",
"-I",
str(path_to_python_include),
str(path_to_python_pkg / c_file_name),
"-o",
str(path_to_shared_lib / (c_file_name[:-1] + "o"))

]

proc = subprocess.run(args, capture_output=True, text=True, check=False, cwd=str(path_to_shared_lib / ".."))
if proc.returncode != 0:
print(proc.stdout)
print(proc.stderr)
raise RuntimeError("Failed to compile GHDL VHPIDIRECT application")

args = [
"gcc",
"-shared",
"-fPIC",
"-o",
str(shared_lib),
str(path_to_shared_lib / "python_pkg.o"),
str(path_to_shared_lib / "python_pkg_vhpidirect_ghdl.o"),
"-l",
python_shared_lib,
"-L",
str(path_to_python_libs),
]

proc = subprocess.run(args, capture_output=True, text=True, check=False, cwd=str(path_to_shared_lib / ".."))
if proc.returncode != 0:
print(proc.stdout)
print(proc.stderr)
raise RuntimeError("Failed to link GHDL VHPIDIRECT application")

7 changes: 7 additions & 0 deletions vunit/sim_if/ghdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ def supports_vhdl_package_generics(cls):
"""
return True

@classmethod
def supported_foreign_language_interfaces(cls):
"""
Returns set of supported foreign interfaces
"""
return set(["VHPIDIRECT_GHDL"])

@classmethod
def supports_vhpi(cls):
"""
Expand Down
2 changes: 1 addition & 1 deletion vunit/sim_if/nvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def supported_foreign_language_interfaces(cls):
"""
Returns set of supported foreign interfaces
"""
return set(["VHPIDIRECT"])
return set(["VHPIDIRECT_NVC"])

def setup_library_mapping(self, project):
"""
Expand Down
12 changes: 10 additions & 2 deletions vunit/vhdl/python/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
#
# Copyright (c) 2014-2023, Lars Asplund [email protected]

import sys
from os import environ
from pathlib import Path
from vunit import VUnit
from vunit.python_pkg import compile_vhpi_application, compile_fli_application, compile_vhpidirect_nvc_application
from vunit.python_pkg import (
compile_vhpi_application,
compile_fli_application,
compile_vhpidirect_nvc_application,
compile_vhpidirect_ghdl_application,
)


def remote_test():
Expand All @@ -15,7 +22,6 @@ def remote_test():

def main():
root = Path(__file__).parent

vu = VUnit.from_argv()
vu.add_vhdl_builtins()
vu.add_python()
Expand All @@ -29,6 +35,8 @@ def main():
compile_fli_application(root, vu)
elif simulator_name == "nvc":
compile_vhpidirect_nvc_application(root, vu)
elif simulator_name == "ghdl":
compile_vhpidirect_ghdl_application(root, vu)

lib = vu.add_library("lib")
lib.add_source_files(root / "test" / "*.vhd")
Expand Down
7 changes: 1 addition & 6 deletions vunit/vhdl/python/src/python_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ package python_pkg is
end package;

package body python_pkg is
function ssin (v : real) return real is
begin
assert false severity failure;
end;

-- @formatter:off
procedure import_module_from_file(module_path, as_module_name : string) is
constant spec_name : string := "__" & as_module_name & "_spec";
Expand All @@ -64,7 +59,7 @@ package body python_pkg is
spec_name & " = spec_from_file_location('" & as_module_name & "', str(Path('" & module_path & "')))" & LF &
as_module_name & " = module_from_spec(" & spec_name & ")" & LF &
"sys.modules['" & as_module_name & "'] = " & as_module_name & LF &
spec_name & ".loader.exec_module(" & as_module_name & ")";
spec_name & ".loader.exec_module(" & as_module_name & ")";
begin
exec(code);
end;
Expand Down
Loading

0 comments on commit 25dcd0e

Please sign in to comment.