Coverage for tsfpga/vivado/simlib_ghdl.py: 81%
27 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 20:51 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project, a project platform for modern FPGA development.
5# https://tsfpga.com
6# https://github.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9from __future__ import annotations
11import re
12from pathlib import Path
13from typing import TYPE_CHECKING
15from tsfpga.system_utils import run_command
17from .simlib_open_source import VivadoSimlibOpenSource
19if TYPE_CHECKING:
20 from vunit.sim_if import SimulatorInterface
21 from vunit.ui import VUnit
24class VivadoSimlibGhdl(VivadoSimlibOpenSource):
25 """
26 Handle Vivado simlib with GHDL.
28 Do not instantiate this class directly.
29 Use factory class :class:`.VivadoSimlib` instead.
30 """
32 # GHDL compilation crashes if its 'workdir' folder does not exist as the analyze command
33 # is executed.
34 _create_library_folder_before_compile = True
36 def __init__(
37 self,
38 vivado_path: Path | None,
39 output_path: Path,
40 vunit_proj: VUnit,
41 simulator_interface: SimulatorInterface,
42 ) -> None:
43 """
44 See superclass :class:`.VivadoSimlibCommon` constructor for details.
45 """
46 self.ghdl_binary = Path(simulator_interface.find_prefix()) / "ghdl"
48 super().__init__(
49 vivado_path=vivado_path,
50 output_path=output_path,
51 vunit_proj=vunit_proj,
52 simulator_interface=simulator_interface,
53 )
55 def _execute_compile(self, output_path: Path, library_name: str, vhd_files: list[str]) -> None:
56 cmd = [
57 str(self.ghdl_binary),
58 "-a",
59 "--ieee=synopsys",
60 "--std=08",
61 f"--workdir={output_path}",
62 f"-P{self.output_path / 'unisim'}",
63 "-fexplicit",
64 "-frelaxed-rules",
65 "--no-vital-checks",
66 "--warn-binding",
67 "--mb-comments",
68 f"--work={library_name}",
69 *vhd_files,
70 ]
72 run_command(cmd, cwd=self.output_path)
74 def _get_simulator_tag(self) -> str:
75 """
76 Return simulator version tag as a string.
77 """
78 cmd = [str(self.ghdl_binary), "--version"]
79 output = run_command(cmd, capture_output=True).stdout
81 match_develop = re.search(pattern=r"^GHDL (\S+) \((\S+)\).*", string=output)
82 if match_develop is not None:
83 return self._format_version(f"ghdl_{match_develop.group(1)}_{match_develop.group(2)}")
85 match_release = re.search(pattern=r"^GHDL (\S+).*", string=output)
86 if match_release is not None:
87 return self._format_version(f"ghdl_{match_release.group(1)}")
89 raise ValueError(f"Could not find GHDL version string: {output}")