Coverage for tsfpga/vivado/simlib_commercial.py: 85%
34 statements
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-20 20:51 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-20 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# --------------------------------------------------------------------------------------------------
9# Standard libraries
10from pathlib import Path
11from typing import Any, Optional
13# First party libraries
14from tsfpga.system_utils import create_file
16# Local folder libraries
17from .common import run_vivado_tcl, to_tcl_path
18from .simlib_common import VivadoSimlibCommon
21class VivadoSimlibCommercial(VivadoSimlibCommon):
22 """
23 Handle Vivado simlib with a commercial simulator.
24 """
26 library_names = ["unisim", "secureip", "unimacro", "unifast", "xpm"]
28 _tcl = (
29 "set_param general.maxthreads 8\n"
30 "compile_simlib "
31 "-simulator {simulator_name} "
32 "-simulator_exec_path {{{simulator_folder}}} "
33 "-directory {{{output_path}}} "
34 "-force "
35 "-family all "
36 "-language all "
37 "-library all "
38 "-no_ip_compile "
39 "-no_systemc_compile "
40 )
42 def __init__(
43 self,
44 vivado_path: Optional[Path],
45 output_path: Path,
46 vunit_proj: Any,
47 simulator_interface: Any,
48 ):
49 """
50 Arguments:
51 output_path: The compiled simlib will be placed here.
52 vunit_proj: The VUnit project that is used to run simulation.
53 simulator_interface: A VUnit SimulatorInterface object.
54 vivado_path: Path to Vivado executable.
55 """
56 self._simulator_folder = Path(simulator_interface.find_prefix())
57 self._simulator_name = self._get_simulator_name(simulator_interface=simulator_interface)
59 super().__init__(vivado_path=vivado_path, output_path=output_path)
61 self._vunit_proj = vunit_proj
63 def _get_simulator_name(self, simulator_interface: Any) -> str:
64 """
65 Used to get the "-simulator" argument to the Vivado "compile_simlib" function.
66 In some cases Vivado needs a different simulator name than what is used in VUnit.
68 Arguments:
69 simulator_interface: A VUnit SimulatorInterface object.
71 Return:
72 str: The simulator name preferred by Vivado.
73 """
74 # Aldec Riviera-PRO is called "rivierapro" in VUnit but Vivado needs the name "riviera"
75 if simulator_interface.name == "rivierapro":
76 return "riviera"
78 # Siemens Questa is called "modelsim" in VUnit but Vivado needs the name "questasim".
79 # See discussion in
80 # https://github.com/VUnit/vunit/issues/834
81 # https://gitlab.com/tsfpga/tsfpga/-/issues/67
82 # Use the simulator installation path to decode whether we are running Questa or
83 # regular ModelSim.
84 if "questa" in str(self._simulator_folder).lower():
85 return "questasim"
87 # In other cases Vivado uses the same name as VUnit.
88 # We do not do typing of the 'simulator_interface', but we know that '.name' is a string.
89 return simulator_interface.name # type: ignore[no-any-return]
91 def _compile(self) -> None:
92 tcl_file = self.output_path / "compile_simlib.tcl"
93 tcl = self._tcl.format(
94 simulator_name=self._simulator_name,
95 simulator_folder=to_tcl_path(self._simulator_folder),
96 output_path=to_tcl_path(self.output_path),
97 )
98 create_file(tcl_file, tcl)
99 compile_ok = run_vivado_tcl(self._vivado_path, tcl_file)
101 if not compile_ok:
102 raise RuntimeError("Vivado simlib compile call failed!")
104 def _get_simulator_tag(self) -> str:
105 """
106 Return e.g. modelsim_modeltech_pe_10_6c or riviera_riviera_pro_2018_10_x64.
107 """
108 simulator_version = self._simulator_folder.parent.name
109 return self._format_version(f"{self._simulator_name}_{simulator_version}")
111 def _add_to_vunit_project(self) -> None:
112 """
113 Add the compiled simlib to your VUnit project.
114 """
115 for library_name in self.library_names:
116 library_path = self.output_path / library_name
117 assert library_path.exists(), library_path
119 self._vunit_proj.add_external_library(library_name, library_path)