Coverage for tsfpga/vivado/simlib_commercial.py: 88%

32 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-29 20:01 +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://gitlab.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9# Standard libraries 

10from pathlib import Path 

11 

12# First party libraries 

13from tsfpga.system_utils import create_file 

14 

15# Local folder libraries 

16from .common import get_vivado_path, run_vivado_tcl, to_tcl_path 

17from .simlib_common import VivadoSimlibCommon 

18 

19 

20class VivadoSimlibCommercial(VivadoSimlibCommon): 

21 

22 """ 

23 Handle Vivado simlib with a commercial simulator. 

24 """ 

25 

26 library_names = ["unisim", "secureip", "unimacro", "unifast", "xpm"] 

27 

28 _tcl = ( 

29 "set_param general.maxthreads 4\n" 

30 "compile_simlib -simulator {simulator_name} -simulator_exec_path {{{simulator_folder}}} " 

31 "-family all -language all -library all -no_ip_compile -dir {{{output_path}}} -force" 

32 ) 

33 

34 def __init__(self, output_path, vunit_proj, simulator_interface, vivado_path): 

35 """ 

36 Arguments: 

37 output_path (pathlib.Path): The compiled simlib will be placed here. 

38 vunit_proj: The VUnit project that is used to run simulation. 

39 simulator_interface: A VUnit SimulatorInterface object. 

40 vivado_path (pathlib.Path): Path to Vivado executable. 

41 """ 

42 self._vunit_proj = vunit_proj 

43 self._vivado_path = get_vivado_path(vivado_path) 

44 

45 self._simulator_folder = Path(simulator_interface.find_prefix()) 

46 self._simulator_name = self._get_simulator_name(simulator_interface=simulator_interface) 

47 

48 self.output_path = output_path / self._get_version_tag() 

49 

50 def _get_simulator_name(self, simulator_interface): 

51 """ 

52 Used to get the "-simulator" argument to the Vivado "compile_simlib" function. 

53 In some cases Vivado needs a different simulator name than what is used in VUnit. 

54 

55 Arguments: 

56 simulator_interface: A VUnit SimulatorInterface object. 

57 

58 Returns: 

59 str: The simulator name preferred by Vivado. 

60 """ 

61 # Aldec Riviera-PRO is called "rivierapro" in VUnit but Vivado needs the name "riviera" 

62 if simulator_interface.name == "rivierapro": 

63 return "riviera" 

64 

65 # Siemens Questa is called "modelsim" in VUnit but Vivado needs the name "questasim". 

66 # See discussion in 

67 # https://github.com/VUnit/vunit/issues/834 

68 # https://gitlab.com/tsfpga/tsfpga/-/issues/67 

69 # Use the simulator installation path to decode whether we are running Questa or 

70 # regular ModelSim. 

71 if "questa" in str(self._simulator_folder).lower(): 

72 return "questasim" 

73 

74 # In other cases Vivado uses the same name as VUnit 

75 return simulator_interface.name 

76 

77 def _compile(self): 

78 tcl_file = self.output_path / "compile_simlib.tcl" 

79 tcl = self._tcl.format( 

80 simulator_name=self._simulator_name, 

81 simulator_folder=to_tcl_path(self._simulator_folder), 

82 output_path=to_tcl_path(self.output_path), 

83 ) 

84 create_file(tcl_file, tcl) 

85 run_vivado_tcl(self._vivado_path, tcl_file) 

86 

87 def _get_simulator_tag(self): 

88 """ 

89 Return e.g. modelsim_modeltech_pe_10_6c or riviera_riviera_pro_2018_10_x64. 

90 """ 

91 simulator_version = self._simulator_folder.parent.name 

92 return self._format_version(f"{self._simulator_name}_{simulator_version}") 

93 

94 def _add_to_vunit_project(self): 

95 """ 

96 Add the compiled simlib to your VUnit project. 

97 """ 

98 for library_name in self.library_names: 

99 library_path = self.output_path / library_name 

100 assert library_path.exists(), library_path 

101 self._vunit_proj.add_external_library(library_name, library_path)