Coverage for hdl_registers/test/test_register_list.py: 100%

148 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 11:11 +0000

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the hdl-registers project, an HDL register generator fast enough to run 

5# in real time. 

6# https://hdl-registers.com 

7# https://github.com/hdl-registers/hdl-registers 

8# -------------------------------------------------------------------------------------------------- 

9 

10import copy 

11from pathlib import Path 

12 

13import pytest 

14 

15from hdl_registers.register import Register 

16from hdl_registers.register_list import RegisterList 

17from hdl_registers.register_modes import REGISTER_MODES 

18 

19 

20def test_from_default_registers(): 

21 register_a = Register(name="a", index=0, mode=REGISTER_MODES["r"], description="AA") 

22 register_b = Register(name="b", index=1, mode=REGISTER_MODES["w"], description="BB") 

23 default_registers = [register_a, register_b] 

24 

25 register_list = RegisterList.from_default_registers( 

26 name="apa", source_definition_file=None, default_registers=default_registers 

27 ) 

28 

29 # Change some things in the register objects to show that they are copied 

30 default_registers.append( 

31 Register(name="c", index=2, mode=REGISTER_MODES["r_w"], description="CC") 

32 ) 

33 register_a.mode = REGISTER_MODES["w"] 

34 register_b.name = "x" 

35 

36 print(register_list.get_register("a").mode) 

37 print(REGISTER_MODES["r"]) 

38 

39 assert len(register_list.register_objects) == 2 

40 assert register_list.get_register("a").mode == REGISTER_MODES["r"] 

41 assert register_list.get_register("b").name == "b" 

42 

43 

44def test_from_default_registers_with_bad_indexes_should_raise_exception(): 

45 register_a = Register(name="a", index=0, mode=REGISTER_MODES["r"], description="") 

46 register_b = Register(name="b", index=0, mode=REGISTER_MODES["w"], description="") 

47 default_registers = [register_a, register_b] 

48 

49 with pytest.raises(ValueError) as exception_info: 

50 RegisterList.from_default_registers( 

51 name="apa", source_definition_file=None, default_registers=default_registers 

52 ) 

53 assert ( 

54 str(exception_info.value) 

55 == 'Default register index mismatch for "b". Got "0", expected "1".' 

56 ) 

57 

58 

59def test_header_constants(): 

60 registers = RegisterList(name="apa", source_definition_file=None) 

61 hest = registers.add_constant("hest", 123, "") 

62 zebra = registers.add_constant("zebra", 456, "description") 

63 

64 assert len(registers.constants) == 2 

65 

66 assert registers.get_constant("hest") == hest 

67 assert registers.get_constant("zebra") == zebra 

68 

69 with pytest.raises(ValueError) as exception_info: 

70 assert registers.get_constant("non existing") is None 

71 assert ( 

72 str(exception_info.value) 

73 == 'Could not find constant "non existing" within register list "apa"' 

74 ) 

75 

76 zebra.value = -5 

77 assert registers.get_constant("zebra").value == -5 

78 

79 

80def test_registers_are_appended_properly_and_can_be_edited_in_place(): 

81 register_array = RegisterList(name="apa", source_definition_file=Path()) 

82 

83 register_hest = register_array.append_register( 

84 name="hest", mode=REGISTER_MODES["r"], description="" 

85 ) 

86 assert register_hest.index == 0 

87 

88 register_zebra = register_array.append_register( 

89 name="zebra", mode=REGISTER_MODES["r"], description="" 

90 ) 

91 assert register_zebra.index == 1 

92 

93 register_hest.description = "new desc" 

94 assert register_array.register_objects[0].description == "new desc" 

95 

96 

97def test_register_arrays_are_appended_properly_and_can_be_edited_in_place(): 

98 register_array = RegisterList(name="apa", source_definition_file=Path()) 

99 

100 register_array_hest = register_array.append_register_array( 

101 name="hest", length=4, description="" 

102 ) 

103 assert register_array_hest.base_index == 0 

104 register_array_hest.append_register(name="foo", mode=REGISTER_MODES["r"], description="") 

105 register_array_hest.append_register(name="bar", mode=REGISTER_MODES["w"], description="") 

106 

107 register_array_zebra = register_array.append_register_array( 

108 name="zebra", length=2, description="" 

109 ) 

110 assert register_array_zebra.base_index == 8 

111 

112 

113def test_get_register(): 

114 register_list = RegisterList(name="apa", source_definition_file=None) 

115 apa = register_list.append_register(name="apa", mode=REGISTER_MODES["r"], description="") 

116 hest = register_list.append_register(name="hest", mode=REGISTER_MODES["r"], description="") 

117 register_array = register_list.append_register_array( 

118 name="register_array", length=3, description="" 

119 ) 

120 zebra = register_array.append_register(name="zebra", mode=REGISTER_MODES["r"], description="") 

121 

122 assert register_list.get_register(register_name="apa") is apa 

123 assert register_list.get_register(register_name="hest") is hest 

124 

125 with pytest.raises(ValueError) as exception_info: 

126 assert register_list.get_register(register_name="non existing") is None 

127 assert ( 

128 str(exception_info.value) 

129 == 'Could not find register "non existing" within register list "apa"' 

130 ) 

131 

132 with pytest.raises(ValueError) as exception_info: 

133 register_list.get_register(register_name="register_array") 

134 assert ( 

135 str(exception_info.value) 

136 == 'Could not find register "register_array" within register list "apa"' 

137 ) 

138 register_list.get_register_array("register_array") 

139 

140 with pytest.raises(ValueError) as exception_info: 

141 register_list.get_register(register_name="zebra") 

142 assert str(exception_info.value) == 'Could not find register "zebra" within register list "apa"' 

143 

144 assert ( 

145 register_list.get_register(register_name="zebra", register_array_name="register_array") 

146 is zebra 

147 ) 

148 

149 with pytest.raises(ValueError) as exception_info: 

150 register_list.get_register(register_name="hest", register_array_name="register_array") 

151 assert ( 

152 str(exception_info.value) 

153 == 'Could not find register "hest" within register array "register_array"' 

154 ) 

155 

156 

157def test_get_register_array(): 

158 register_list = RegisterList(name="apa", source_definition_file=None) 

159 

160 hest = register_list.append_register_array(name="hest", length=3, description="") 

161 hest.append_register(name="foo", mode=REGISTER_MODES["r"], description="") 

162 

163 zebra = register_list.append_register_array(name="zebra", length=2, description="") 

164 zebra.append_register(name="bar", mode=REGISTER_MODES["r"], description="") 

165 

166 register_list.append_register(name="register", mode=REGISTER_MODES["r"], description="") 

167 

168 assert register_list.get_register_array("hest") is hest 

169 assert register_list.get_register_array("zebra") is zebra 

170 

171 with pytest.raises(ValueError) as exception_info: 

172 register_list.get_register_array("non existing") 

173 assert ( 

174 str(exception_info.value) 

175 == 'Could not find register array "non existing" within register list "apa"' 

176 ) 

177 

178 with pytest.raises(ValueError) as exception_info: 

179 register_list.get_register_array("register") 

180 assert ( 

181 str(exception_info.value) 

182 == 'Could not find register array "register" within register list "apa"' 

183 ) 

184 register_list.get_register("register") 

185 

186 

187def test_get_register_index(): 

188 register_list = RegisterList(name=None, source_definition_file=None) 

189 

190 register_list.append_register(name="apa", mode=REGISTER_MODES["r"], description="") 

191 register_list.append_register(name="hest", mode=REGISTER_MODES["r"], description="") 

192 

193 zebra = register_list.append_register_array(name="zebra", length=2, description="") 

194 zebra.append_register(name="bar", mode=REGISTER_MODES["r"], description="") 

195 zebra.append_register(name="baz", mode=REGISTER_MODES["r"], description="") 

196 

197 assert register_list.get_register_index(register_name="apa") == 0 

198 assert register_list.get_register_index(register_name="hest") == 1 

199 assert ( 

200 register_list.get_register_index( 

201 register_name="bar", register_array_name="zebra", register_array_index=0 

202 ) 

203 == 2 

204 ) 

205 assert ( 

206 register_list.get_register_index( 

207 register_name="baz", register_array_name="zebra", register_array_index=1 

208 ) 

209 == 5 

210 ) 

211 

212 

213def test_repr_basic(): 

214 # Check that repr is an actual representation, not just "X object at 0xABCDEF" 

215 assert "apa" in repr(RegisterList(name="apa", source_definition_file=Path())) 

216 

217 # Different name 

218 assert repr(RegisterList(name="apa", source_definition_file=Path())) != repr( 

219 RegisterList(name="hest", source_definition_file=Path()) 

220 ) 

221 

222 # Different source_definition_file 

223 assert repr(RegisterList(name="apa", source_definition_file=Path())) != repr( 

224 RegisterList(name="apa", source_definition_file=Path("./zebra")) 

225 ) 

226 

227 

228def test_repr_with_constant_added(): 

229 register_list_a = RegisterList(name="apa", source_definition_file=Path()) 

230 register_list_b = RegisterList(name="apa", source_definition_file=Path()) 

231 assert repr(register_list_a) == repr(register_list_b) 

232 

233 register_list_a.add_constant(name="zebra", value=3, description="") 

234 

235 assert repr(register_list_a) != repr(register_list_b) 

236 

237 

238def test_repr_with_register_appended(): 

239 register_list_a = RegisterList(name="apa", source_definition_file=Path()) 

240 register_list_b = RegisterList(name="apa", source_definition_file=Path()) 

241 assert repr(register_list_a) == repr(register_list_b) 

242 

243 register_list_a.append_register(name="zebra", mode=REGISTER_MODES["w"], description="") 

244 

245 assert repr(register_list_a) != repr(register_list_b) 

246 

247 

248def test_repr_with_register_array_appended(): 

249 register_list_a = RegisterList(name="apa", source_definition_file=Path()) 

250 register_list_b = RegisterList(name="apa", source_definition_file=Path()) 

251 assert repr(register_list_a) == repr(register_list_b) 

252 

253 register_list_a.append_register_array(name="zebra", length=4, description="") 

254 

255 assert repr(register_list_a) != repr(register_list_b) 

256 

257 

258def test_deep_copy_of_register_list_actually_copies_everything(): 

259 original_list = RegisterList("original", Path("/original_file.txt")) 

260 original_list.add_constant("original_constant", value=2, description="original constant") 

261 original_list.append_register( 

262 "original_register", REGISTER_MODES["w"], description="original register" 

263 ) 

264 original_array = original_list.append_register_array("original_array", length=4, description="") 

265 original_array.append_register( 

266 name="original_register_in_array", mode=REGISTER_MODES["r"], description="" 

267 ) 

268 

269 copied_list = copy.deepcopy(original_list) 

270 

271 assert copied_list.constants is not original_list.constants 

272 assert copied_list.constants[0] is not original_list.constants[0] 

273 

274 copied_list.add_constant(name="new_constant", value=5, description="") 

275 assert len(copied_list.constants) == 2 

276 assert len(original_list.constants) == 1 

277 

278 assert copied_list.register_objects is not original_list.register_objects 

279 assert copied_list.register_objects[0] is not original_list.register_objects[0] 

280 

281 # Original register in position 0, original register array in position 1, new register in 2 

282 copied_list.append_register(name="new_register", mode=REGISTER_MODES["r"], description="") 

283 assert len(copied_list.register_objects) == 3 

284 assert len(original_list.register_objects) == 2 

285 

286 assert copied_list.register_objects[1] is not original_list.register_objects[1] 

287 assert ( 

288 copied_list.register_objects[1].registers is not original_list.register_objects[1].registers 

289 ) 

290 assert ( 

291 copied_list.register_objects[1].registers[0] 

292 is not original_list.register_objects[1].registers[0] 

293 ) 

294 copied_list.register_objects[1].append_register( 

295 name="new_register_in_array", mode=REGISTER_MODES["r_w"], description="" 

296 ) 

297 assert len(copied_list.register_objects[1].registers) == 2 

298 assert len(original_list.register_objects[1].registers) == 1