Coverage for tsfpga/vivado/simlib_nvc.py: 73%
30 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 VivadoSimlibNvc(VivadoSimlibOpenSource):
25 """
26 Handle Vivado simlib with NVC.
28 Do not instantiate this class directly.
29 Use factory class :class:`.VivadoSimlib` instead.
30 """
32 # NVC compilation gives a warning if the folder exist when the analyze command is executed.
33 _create_library_folder_before_compile = False
35 def __init__(
36 self,
37 vivado_path: Path | None,
38 output_path: Path,
39 vunit_proj: VUnit,
40 simulator_interface: SimulatorInterface,
41 ) -> None:
42 """
43 See superclass :class:`.VivadoSimlibCommon` constructor for details.
44 """
45 self.nvc_binary = Path(simulator_interface.find_prefix()) / "nvc"
47 super().__init__(
48 vivado_path=vivado_path,
49 output_path=output_path,
50 vunit_proj=vunit_proj,
51 simulator_interface=simulator_interface,
52 )
54 def _execute_compile(
55 self,
56 output_path: Path, # noqa: ARG002
57 library_name: str,
58 vhd_files: list[str],
59 ) -> None:
60 cmd = [
61 str(self.nvc_binary),
62 f"--work={library_name}",
63 "--std=2008",
64 "-M",
65 "64m",
66 ]
67 if library_name != "unisim":
68 cmd.append(
69 f"--map=unisim:{self.output_path / 'unisim'}",
70 )
72 cmd += ["-a", *vhd_files]
74 run_command(cmd, cwd=self.output_path)
76 def _get_simulator_tag(self) -> str:
77 """
78 Return simulator version tag as a string.
79 """
80 cmd = [str(self.nvc_binary), "--version"]
81 output = run_command(cmd, capture_output=True).stdout
83 match_release = re.search(pattern=r"^nvc (\S+) \(Using.*", string=output)
84 if match_release is not None:
85 return self._format_version(f"nvc_{match_release.group(1)}")
87 match_develop = re.search(pattern=r"^nvc (\S+) \((\S+)\) \(Using.*", string=output)
88 if match_develop is not None:
89 return self._format_version(f"nvc_{match_develop.group(1)}_{match_develop.group(2)}")
91 raise ValueError(f"Could not find NVC version string: {output}")