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 

9from pathlib import Path 

10from unittest import TestCase 

11from unittest.mock import ANY, patch 

12 

13import pytest 

14 

15from tsfpga.module import BaseModule, get_modules 

16from tsfpga.system_utils import create_file, create_directory 

17 

18 

19def test_file_list_filtering(tmp_path): 

20 module_name = "zebra" 

21 path = tmp_path / module_name 

22 

23 create_directory(path / "folder_should_not_be_included") 

24 create_file(path / "should_not_be_included.apa") 

25 

26 synth_files = [ 

27 create_file(path / "syn.v"), 

28 create_file(path / "rtl" / "syn.v"), 

29 create_file(path / "src" / "syn.vhd"), 

30 create_file(path / "hdl" / "rtl" / "syn.vhd"), 

31 create_file(path / "hdl" / "package" / "syn.vhd"), 

32 ] 

33 

34 test_files = [ 

35 create_file(path / "test" / "test.v"), 

36 create_file(path / "rtl" / "tb" / "test.vhd"), 

37 ] 

38 

39 sim_files = [create_file(path / "sim" / "sim.vhd")] 

40 

41 my_module = BaseModule(path, "zebra") 

42 

43 files = [file.path for file in my_module.get_synthesis_files()] 

44 assert set(files) == set(synth_files) 

45 

46 files = [file.path for file in my_module.get_simulation_files()] 

47 assert set(files) == set(synth_files + test_files + sim_files) 

48 

49 files = [file.path for file in my_module.get_simulation_files(include_tests=False)] 

50 assert set(files) == set(synth_files + sim_files) 

51 

52 files = [file.path for file in my_module.get_simulation_files(files_include=synth_files)] 

53 assert set(files) == set(synth_files) 

54 

55 files = [file.path for file in my_module.get_simulation_files(files_avoid=synth_files)] 

56 assert set(files) == set(test_files + sim_files) 

57 

58 files = [file.path for file in my_module.get_formal_files()] 

59 assert set(files) == set(synth_files) 

60 

61 

62def test_get_synthesis_files_calls_get_simulation_files_with_correct_arguments(): 

63 module = BaseModule(path=Path(), library_name="") 

64 with patch("tsfpga.module.BaseModule.get_synthesis_files") as get_synthesis_files: 

65 module.get_simulation_files(files_include=True, files_avoid=False, apa=123) 

66 get_synthesis_files.assert_called_once_with(files_include=True, files_avoid=False, apa=123) 

67 

68 

69def test_get_formal_files_calls_get_simulation_files_with_correct_arguments(): 

70 module = BaseModule(path=Path(), library_name="") 

71 with patch("tsfpga.module.BaseModule.get_synthesis_files") as get_synthesis_files: 

72 module.get_formal_files(files_include=True, files_avoid=False, apa=123) 

73 get_synthesis_files.assert_called_once_with(files_include=True, files_avoid=False, apa=123) 

74 

75 

76def test_scoped_constraints(tmp_path): 

77 module_path = tmp_path / "apa" 

78 create_file(module_path / "src" / "hest.vhd") 

79 create_file(module_path / "scoped_constraints" / "hest.tcl") 

80 

81 my_module = BaseModule(module_path, "apa") 

82 scoped_constraints = my_module.get_scoped_constraints() 

83 assert len(scoped_constraints) == 1 

84 assert scoped_constraints[0].ref == "hest" 

85 

86 

87def test_scoped_constraint_entity_not_existing_should_raise_error(tmp_path): 

88 module_path = tmp_path / "apa" 

89 create_file(module_path / "scoped_constraints" / "hest.tcl") 

90 

91 module = BaseModule(module_path, "apa") 

92 with pytest.raises(FileNotFoundError) as exception_info: 

93 module.get_scoped_constraints() 

94 assert str(exception_info.value).startswith("Could not find a matching entity file") 

95 

96 

97def test_can_cast_to_string_without_error(): 

98 str(BaseModule(Path("dummy"), "dummy")) 

99 

100 

101def test_test_case_name(): 

102 assert ( 

103 BaseModule.test_case_name(generics=dict(apa=3, hest_zebra="foo")) == "apa_3.hest_zebra_foo" 

104 ) 

105 assert ( 

106 BaseModule.test_case_name(name="foo", generics=dict(apa=3, hest_zebra="bar")) 

107 == "foo.apa_3.hest_zebra_bar" 

108 ) 

109 

110 

111def test_getting_registers_calls_registers_hook(tmp_path): 

112 with patch("tsfpga.module.from_toml", autospec=True) as from_toml, patch( 

113 "tsfpga.module.BaseModule.registers_hook", autospec=True 

114 ) as registers_hook: 

115 create_file(tmp_path / "a" / "regs_a.toml") 

116 module = BaseModule(path=tmp_path / "a", library_name="a") 

117 registers = module.registers 

118 

119 # TOML file exists so register creation from TOML should run 

120 from_toml.assert_called_once() 

121 registers_hook.assert_called_once() 

122 assert registers is not None 

123 

124 with patch("tsfpga.module.from_toml", autospec=True) as from_toml, patch( 

125 "tsfpga.module.BaseModule.registers_hook", autospec=True 

126 ) as registers_hook: 

127 module = BaseModule(path=tmp_path / "b", library_name="b") 

128 registers = module.registers 

129 

130 # TOML file does not exist, so register creation from TOML should not run 

131 from_toml.assert_not_called() 

132 # Register hook shall still run however 

133 registers_hook.assert_called_once() 

134 assert registers is None 

135 

136 

137@pytest.mark.usefixtures("fixture_tmp_path") 

138class TestGetModules(TestCase): 

139 

140 tmp_path = None 

141 

142 def setUp(self): 

143 create_directory(self.tmp_path / "a") 

144 create_directory(self.tmp_path / "b") 

145 create_directory(self.tmp_path / "c") 

146 

147 self.modules_folders = [self.tmp_path] 

148 

149 def test_name_filtering_include(self): 

150 modules = get_modules(self.modules_folders, names_include=["a", "b"]) 

151 assert set(module.name for module in modules) == set(["a", "b"]) 

152 

153 def test_name_filtering_avoid(self): 

154 modules = get_modules(self.modules_folders, names_avoid=["a", "b"]) 

155 assert set(module.name for module in modules) == set(["c"]) 

156 

157 def test_name_filtering_include_and_avoid(self): 

158 modules = get_modules( 

159 self.modules_folders, names_include=["a", "c"], names_avoid=["b", "c"] 

160 ) 

161 assert set(module.name for module in modules) == set(["a"]) 

162 

163 def test_library_name_does_not_have_lib_suffix(self): 

164 modules = get_modules(self.modules_folders) 

165 assert set(module.library_name for module in modules) == set(["a", "b", "c"]) 

166 

167 def test_library_name_has_lib_suffix(self): 

168 modules = get_modules(self.modules_folders, library_name_has_lib_suffix=True) 

169 assert set(module.library_name for module in modules) == set(["a_lib", "b_lib", "c_lib"]) 

170 

171 def test_stray_file_can_exist_in_modules_folder_without_error(self): 

172 create_file(self.tmp_path / "text_file.txt") 

173 modules = get_modules(self.modules_folders) 

174 assert len(modules) == 3 

175 

176 def test_local_override_of_module_type(self): 

177 module_file_content = """ 

178from tsfpga.module import BaseModule 

179 

180class Module(BaseModule): 

181 

182 def id(self): 

183 return """ 

184 

185 create_file(self.tmp_path / "a" / "module_a.py", module_file_content + '"a"') 

186 create_file(self.tmp_path / "b" / "module_b.py", module_file_content + '"b"') 

187 

188 modules = get_modules(self.modules_folders) 

189 

190 assert len(modules) == 3 

191 for module in modules: 

192 if module.name == "a": 

193 assert module.id() == "a" 

194 elif module.name == "b": 

195 assert module.id() == "b" 

196 elif module.name == "c": 

197 assert isinstance(module, BaseModule) 

198 else: 

199 assert False 

200 

201 @patch("tsfpga.module.from_toml", autospec=True) 

202 def test_register_object_creation_called_when_getting_synthesis_files(self, from_toml): 

203 toml_file = create_file(self.tmp_path / "a" / "regs_a.toml") 

204 

205 module = get_modules(self.modules_folders).get("a") 

206 module.get_synthesis_files() 

207 module.get_synthesis_files() 

208 

209 from_toml.assert_called_once_with("a", toml_file, ANY) 

210 

211 @patch("tsfpga.module.from_toml", autospec=True) 

212 def test_register_object_creation_called_when_getting_simulation_files(self, from_toml): 

213 toml_file = create_file(self.tmp_path / "a" / "regs_a.toml") 

214 

215 module = get_modules(self.modules_folders).get("a") 

216 module.get_simulation_files() 

217 module.get_simulation_files() 

218 

219 from_toml.assert_called_once_with("a", toml_file, ANY) 

220 

221 @patch("tsfpga.module.from_toml", autospec=True) 

222 def test_register_object_creation_called_once_when_getting_mixed_files(self, from_toml): 

223 toml_file = create_file(self.tmp_path / "a" / "regs_a.toml") 

224 

225 module = get_modules(self.modules_folders).get("a") 

226 module.get_synthesis_files() 

227 module.get_simulation_files() 

228 

229 from_toml.assert_called_once_with("a", toml_file, ANY)