Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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# -------------------------------------------------------------------------------------------------- 

8 

9import re 

10import subprocess 

11from pathlib import Path 

12 

13from tsfpga import DEFAULT_FILE_ENCODING 

14from tsfpga.system_utils import create_directory 

15from .common import get_vivado_path 

16from .simlib_common import VivadoSimlibCommon 

17 

18 

19class VivadoSimlibGhdl(VivadoSimlibCommon): 

20 

21 """ 

22 Handle Vivado simlib with GHDL. 

23 """ 

24 

25 _libraries = ["unisim", "secureip", "unimacro", "unifast"] 

26 

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) 

37 

38 self.ghdl_binary = Path(simulator_interface.find_prefix()) / "ghdl" 

39 

40 self._output_path = output_path / self._get_version_tag() 

41 

42 def _compile(self): 

43 vivado_libraries_path = self._vivado_path.parent.parent / "data" / "vhdl" / "src" 

44 

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") 

49 

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 / (vhd_file_base + ".vhd") 

56 assert vhd_file.exists, vhd_file 

57 self._compile_ghdl_file(vhd_file, "unisim") 

58 

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") 

62 

63 retarget_dir = library_path / "retarget" 

64 for vhd_file in retarget_dir.glob("*.vhd"): 

65 self._compile_ghdl_file(vhd_file, "unisim") 

66 

67 def _compile_secureip(self, library_path): 

68 for vhd_file in library_path.glob("*.vhd"): 

69 self._compile_ghdl_file(vhd_file, "secureip") 

70 

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") 

75 

76 for vhd_file in self._iterate_compile_order(library_path): 

77 self._compile_ghdl_file(vhd_file, "unimacro") 

78 

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") 

82 

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 

92 

93 def _compile_ghdl_file(self, vhd_file, library_name): 

94 print(f"Compiling {vhd_file} into {library_name}") 

95 workdir = self._output_path / library_name / "v08" 

96 create_directory(workdir, empty=False) 

97 cmd = [ 

98 self.ghdl_binary, 

99 "-a", 

100 "--ieee=synopsys", 

101 "--std=08", 

102 "--workdir=" + str(workdir.resolve()), 

103 "-P" + str(self._output_path), 

104 "-fexplicit", 

105 "-frelaxed-rules", 

106 "--no-vital-checks", 

107 "--warn-binding", 

108 "--mb-comments", 

109 "--work=" + library_name, 

110 str(vhd_file.resolve()), 

111 ] 

112 subprocess.check_call(cmd, cwd=self._output_path) 

113 

114 def _get_simulator_tag(self): 

115 """ 

116 Return simulator version tag 

117 """ 

118 cmd = [self.ghdl_binary, "--version"] 

119 output = subprocess.check_output(cmd).decode() 

120 

121 regexp_with_tag = re.compile(r"^GHDL (\S+) \((\S+)\).*") 

122 match = regexp_with_tag.search(output) 

123 if match is not None: 

124 return self._format_version(f"ghdl_{match.group(1)}_{match.group(2)}") 

125 

126 regexp_without_tag = re.compile(r"^GHDL (\S+).*") 

127 match = regexp_without_tag.search(output) 

128 if match is not None: 

129 return self._format_version("ghdl_" + match.group(1)) 

130 

131 raise ValueError("Could not find GHDL version string: " + output) 

132 

133 def _add_to_vunit_project(self): 

134 """ 

135 Add the compiled simlib to your VUnit project. 

136 """ 

137 for library in self._libraries: 

138 library_path = self._output_path / library / "v08" 

139 assert library_path.exists(), library_path 

140 self._vunit_proj.add_external_library(library, library_path)