Coverage for tsfpga/vivado/simlib_ghdl.py: 47%
73 statements
« prev ^ index » next coverage.py v6.4, created at 2022-05-28 04:01 +0000
« prev ^ index » next coverage.py v6.4, created at 2022-05-28 04:01 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project.
5# https://tsfpga.com
6# https://gitlab.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9import re
10import subprocess
11from pathlib import Path
13from tsfpga import DEFAULT_FILE_ENCODING
14from tsfpga.system_utils import create_directory
15from .common import get_vivado_path
16from .simlib_common import VivadoSimlibCommon
19class VivadoSimlibGhdl(VivadoSimlibCommon):
21 """
22 Handle Vivado simlib with GHDL.
23 """
25 library_names = ["unisim", "secureip", "unimacro", "unifast"]
27 def __init__(self, output_path, vunit_proj, simulator_interface, vivado_path):
28 """
29 Arguments:
30 output_path (pathlib.Path): The compiled simlib will be placed here.
31 vunit_proj: The VUnit project that is used to run simulation.
32 simulator_interface: A VUnit SimulatorInterface class.
33 vivado_path (pathlib.Path): Path to Vivado executable.
34 """
35 self._vunit_proj = vunit_proj
36 self._vivado_path = get_vivado_path(vivado_path)
38 self.ghdl_binary = Path(simulator_interface.find_prefix()) / "ghdl"
40 self.output_path = output_path / self._get_version_tag()
42 def _compile(self):
43 vivado_libraries_path = self._vivado_path.parent.parent / "data" / "vhdl" / "src"
45 self._compile_unisim(vivado_libraries_path / "unisims")
46 self._compile_secureip(vivado_libraries_path / "unisims" / "secureip")
47 self._compile_unimacro(vivado_libraries_path / "unimacro")
48 self._compile_unifast(vivado_libraries_path / "unifast" / "primitive")
50 def _compile_unisim(self, library_path):
51 for vhd_file_base in [
52 "unisim_VPKG",
53 "unisim_retarget_VCOMP",
54 ]:
55 vhd_file = library_path / f"{vhd_file_base}.vhd"
56 assert vhd_file.exists, vhd_file
57 self._compile_ghdl_file(vhd_file, "unisim")
59 primitive_dir = library_path / "primitive"
60 for vhd_file in self._iterate_compile_order(primitive_dir):
61 self._compile_ghdl_file(vhd_file, "unisim")
63 retarget_dir = library_path / "retarget"
64 for vhd_file in retarget_dir.glob("*.vhd"):
65 self._compile_ghdl_file(vhd_file, "unisim")
67 def _compile_secureip(self, library_path):
68 for vhd_file in library_path.glob("*.vhd"):
69 self._compile_ghdl_file(vhd_file, "secureip")
71 def _compile_unimacro(self, library_path):
72 vhd_file = library_path / "unimacro_VCOMP.vhd"
73 assert vhd_file.exists, vhd_file
74 self._compile_ghdl_file(vhd_file, "unimacro")
76 for vhd_file in self._iterate_compile_order(library_path):
77 self._compile_ghdl_file(vhd_file, "unimacro")
79 def _compile_unifast(self, library_path):
80 for vhd_file in self._iterate_compile_order(library_path):
81 self._compile_ghdl_file(vhd_file, "unifast")
83 @staticmethod
84 def _iterate_compile_order(library_path):
85 with open(
86 library_path / "vhdl_analyze_order", encoding=DEFAULT_FILE_ENCODING
87 ) as file_handle:
88 for vhd_file_base in file_handle.readlines():
89 vhd_file = library_path / vhd_file_base.strip()
90 assert vhd_file.exists(), vhd_file
91 yield vhd_file
93 def _compile_ghdl_file(self, vhd_file, library_name):
94 print(f"Compiling {vhd_file} into {library_name}")
96 workdir = self.output_path / library_name
97 create_directory(workdir, empty=False)
99 cmd = [
100 self.ghdl_binary,
101 "-a",
102 "--ieee=synopsys",
103 "--std=08",
104 f"--workdir={str(workdir.resolve())}",
105 f"-P{str(self.output_path / 'unisim')}",
106 "-fexplicit",
107 "-frelaxed-rules",
108 "--no-vital-checks",
109 "--warn-binding",
110 "--mb-comments",
111 f"--work={library_name}",
112 str(vhd_file.resolve()),
113 ]
114 subprocess.check_call(cmd, cwd=self.output_path)
116 def _get_simulator_tag(self):
117 """
118 Return simulator version tag
119 """
120 cmd = [self.ghdl_binary, "--version"]
121 output = subprocess.check_output(cmd).decode()
123 regexp_with_tag = re.compile(r"^GHDL (\S+) \((\S+)\).*")
124 match = regexp_with_tag.search(output)
125 if match is not None:
126 return self._format_version(f"ghdl_{match.group(1)}_{match.group(2)}")
128 regexp_without_tag = re.compile(r"^GHDL (\S+).*")
129 match = regexp_without_tag.search(output)
130 if match is not None:
131 return self._format_version(f"ghdl_{match.group(1)}")
133 raise ValueError(f"Could not find GHDL version string: {output}")
135 def _add_to_vunit_project(self):
136 """
137 Add the compiled simlib to your VUnit project.
138 """
139 for library_name in self.library_names:
140 library_path = self.output_path / library_name
141 assert library_path.exists(), library_path
142 self._vunit_proj.add_external_library(library_name, library_path)