Coverage for hdl_registers/test/unit/test_bit_vector.py: 100%

114 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-29 22:03 +0000

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

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

3# 

4# This file is part of the hdl_registers project, a HDL register generator fast enough to be run 

5# in real time. 

6# https://hdl-registers.com 

7# https://gitlab.com/hdl_registers/hdl_registers 

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

9 

10# Third party libraries 

11import pytest 

12 

13# First party libraries 

14from hdl_registers.bit_vector import BitVector 

15from hdl_registers.register_field_type import Signed, SignedFixedPoint, Unsigned, UnsignedFixedPoint 

16 

17 

18def test_get_value(): 

19 bit = BitVector(name="", base_index=2, description="", width=4, default_value="0000") 

20 

21 register_value = int("111000011", base=2) 

22 assert bit.get_value(register_value) == 0 

23 

24 register_value = int("000111100", base=2) 

25 assert bit.get_value(register_value) == 15 

26 

27 register_value = int("101010101", base=2) 

28 assert bit.get_value(register_value) == 5 

29 

30 # Test field_type 

31 field = BitVector( 

32 name="", 

33 base_index=2, 

34 description="", 

35 width=16, 

36 default_value="0" * 16, 

37 field_type=SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 

38 ) 

39 register_value = 0b11111111_00000011_11111111_11111100 

40 assert field.get_value(register_value) == -0.00390625 

41 

42 

43def test_max_binary_value(): 

44 bit_vector = BitVector( 

45 name="", base_index=0, description="", width=2, default_value=format(0, "02b") 

46 ) 

47 assert bit_vector.max_binary_value == 0b11 

48 

49 bit_vector = BitVector( 

50 name="", base_index=0, description="", width=32, default_value=format(0, "032b") 

51 ) 

52 assert bit_vector.max_binary_value == 0b11111111_11111111_11111111_11111111 

53 

54 # Test with base_index > 0 

55 bit_vector = BitVector( 

56 name="", base_index=4, description="", width=4, default_value=format(0, "04b") 

57 ) 

58 assert bit_vector.max_binary_value == 0b1111 

59 

60 

61def test_set_value(): 

62 bit_vector = BitVector( 

63 name="", base_index=0, description="", width=2, default_value=format(0, "02b") 

64 ) 

65 assert bit_vector.set_value(0b10) == 0b10 

66 assert bit_vector.set_value(0b11) == 0b11 

67 

68 with pytest.raises(ValueError): 

69 bit_vector.set_value(0b111) 

70 

71 bit_vector = BitVector( 

72 name="", base_index=2, description="", width=2, default_value=format(0, "02b") 

73 ) 

74 assert bit_vector.set_value(0b10) == 0b1000 

75 

76 bit_vector = BitVector( 

77 name="", base_index=3, description="", width=4, default_value=format(0, "04b") 

78 ) 

79 assert bit_vector.set_value(0b1111) == 0b1111000 

80 

81 bit_vector0 = BitVector(name="", base_index=0, description="", width=2, default_value="00") 

82 bit_vector1 = BitVector(name="", base_index=2, description="", width=4, default_value="0000") 

83 bit_vector2 = BitVector(name="", base_index=6, description="", width=3, default_value="000") 

84 

85 register_value = int("111000011", base=2) 

86 value0 = bit_vector0.set_value(bit_vector0.get_value(register_value)) 

87 value1 = bit_vector1.set_value(bit_vector1.get_value(register_value)) 

88 value2 = bit_vector2.set_value(bit_vector2.get_value(register_value)) 

89 assert value0 | value1 | value2 == register_value 

90 

91 register_value = int("000111100", base=2) 

92 value0 = bit_vector0.set_value(bit_vector0.get_value(register_value)) 

93 value1 = bit_vector1.set_value(bit_vector1.get_value(register_value)) 

94 value2 = bit_vector2.set_value(bit_vector2.get_value(register_value)) 

95 assert value0 | value1 | value2 == register_value 

96 

97 register_value = int("101010101", base=2) 

98 value0 = bit_vector0.set_value(bit_vector0.get_value(register_value)) 

99 value1 = bit_vector1.set_value(bit_vector1.get_value(register_value)) 

100 value2 = bit_vector2.set_value(bit_vector2.get_value(register_value)) 

101 assert value0 | value1 | value2 == register_value 

102 

103 # Test field_type 

104 field = BitVector( 

105 name="", 

106 base_index=2, 

107 description="", 

108 width=16, 

109 default_value="0" * 16, 

110 field_type=SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 

111 ) 

112 assert field.set_value(-0.00390625) == 0b11_11111111_11111100 

113 

114 

115def test_repr(): 

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

117 assert "apa" in repr( 

118 BitVector(name="apa", base_index=0, description="", width=1, default_value="0") 

119 ) 

120 

121 # Different name 

122 assert repr( 

123 BitVector(name="apa", base_index=0, description="", width=1, default_value="0") 

124 ) != repr(BitVector(name="hest", base_index=0, description="", width=1, default_value="0")) 

125 

126 # Different base_index 

127 assert repr( 

128 BitVector(name="apa", base_index=0, description="", width=1, default_value="0") 

129 ) != repr(BitVector(name="apa", base_index=1, description="", width=1, default_value="0")) 

130 

131 # Different description 

132 assert repr( 

133 BitVector(name="apa", base_index=0, description="Blah", width=1, default_value="0") 

134 ) != repr(BitVector(name="apa", base_index=0, description="Gaah", width=1, default_value="0")) 

135 

136 # Different width 

137 assert repr( 

138 BitVector(name="apa", base_index=0, description="", width=1, default_value="1") 

139 ) != repr(BitVector(name="apa", base_index=0, description="", width=2, default_value="11")) 

140 

141 # Different default_value 

142 assert repr( 

143 BitVector(name="apa", base_index=0, description="", width=1, default_value="1") 

144 ) != repr(BitVector(name="apa", base_index=0, description="", width=1, default_value="0")) 

145 

146 # Different field_type 

147 field0 = BitVector( 

148 name="apa", 

149 base_index=0, 

150 description="", 

151 width=8, 

152 default_value="0" * 8, 

153 field_type=UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2), 

154 ) 

155 field1 = BitVector( 

156 name="apa", 

157 base_index=0, 

158 description="", 

159 width=8, 

160 default_value="0" * 8, 

161 field_type=UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2), 

162 ) 

163 field2 = BitVector( 

164 name="apa", 

165 base_index=0, 

166 description="", 

167 width=8, 

168 default_value="0" * 8, 

169 field_type=UnsignedFixedPoint(max_bit_index=8, min_bit_index=-1), 

170 ) 

171 assert repr(field0) == repr(field1) != repr(field2) 

172 

173 

174def test_invalid_width(): 

175 with pytest.raises(ValueError) as exception_info: 

176 BitVector(name="foo", base_index=0, width="4", description="", default_value="0000") 

177 assert ( 

178 str(exception_info.value) 

179 == 'Bit vector "foo" should have integer value for "width". Got: "4".' 

180 ) 

181 

182 with pytest.raises(ValueError) as exception_info: 

183 BitVector(name="foo", base_index=0, width=33, description="", default_value="0") 

184 assert str(exception_info.value) == 'Invalid bit vector width for "foo". Got: "33".' 

185 

186 with pytest.raises(ValueError) as exception_info: 

187 BitVector(name="foo", base_index=0, width=0, description="", default_value="0") 

188 assert str(exception_info.value) == 'Invalid bit vector width for "foo". Got: "0".' 

189 

190 

191def test_invalid_default_value_should_raise_exception(): 

192 with pytest.raises(ValueError) as exception_info: 

193 BitVector(name="hest", base_index=0, description="", width=4, default_value=1111) 

194 assert str(exception_info.value) == ( 

195 'Bit vector "hest" should have string value for "default_value". Got: "1111"' 

196 ) 

197 

198 with pytest.raises(ValueError) as exception_info: 

199 BitVector(name="hest", base_index=0, description="", width=4, default_value="11") 

200 assert str(exception_info.value) == ( 

201 'Bit vector "hest" should have "default_value" of length 4. Got: "11".' 

202 ) 

203 

204 with pytest.raises(ValueError) as exception_info: 

205 BitVector(name="hest", base_index=0, description="", width=4, default_value="1121") 

206 assert str(exception_info.value) == ( 

207 'Bit vector "hest" invalid binary value for "default_value". Got: "1121".' 

208 ) 

209 

210 

211def test_can_update_default_value(): 

212 bit_vector = BitVector(name="hest", base_index=0, description="", width=4, default_value="1111") 

213 assert bit_vector.default_value == "1111" 

214 

215 bit_vector.default_value = "0000" 

216 assert bit_vector.default_value == "0000" 

217 

218 

219def test_updating_to_invalid_default_value_should_raise_exception(): 

220 # Create with a valid default_value 

221 bit_vector = BitVector(name="hest", base_index=0, description="", width=4, default_value="1111") 

222 

223 # Update to an invalid value 

224 with pytest.raises(ValueError) as exception_info: 

225 bit_vector.default_value = 1111 

226 assert str(exception_info.value) == ( 

227 'Bit vector "hest" should have string value for "default_value". Got: "1111"' 

228 ) 

229 

230 

231def test_default_value_uint(): 

232 bit_vector = BitVector(name="apa", base_index=0, description="", width=4, default_value="0000") 

233 assert bit_vector.default_value_uint == 0 

234 

235 bit_vector.default_value = "0010" 

236 assert bit_vector.default_value_uint == 2 

237 

238 bit_vector.default_value = "1001" 

239 assert bit_vector.default_value_uint == 9 

240 

241 

242def test_field_type(): 

243 bit_vector = BitVector(name="", base_index=0, description="", width=4, default_value="1111") 

244 assert isinstance(bit_vector.field_type, Unsigned) 

245 

246 bit_vector = BitVector( 

247 name="", base_index=0, description="", width=4, default_value="1111", field_type=Unsigned() 

248 ) 

249 assert isinstance(bit_vector.field_type, Unsigned) 

250 

251 bit_vector = BitVector( 

252 name="", base_index=0, description="", width=4, default_value="1111", field_type=Signed() 

253 ) 

254 assert isinstance(bit_vector.field_type, Signed) 

255 

256 bit_vector = BitVector( 

257 name="", 

258 base_index=0, 

259 description="", 

260 width=4, 

261 default_value="1111", 

262 field_type=SignedFixedPoint(max_bit_index=7, min_bit_index=-2), 

263 ) 

264 assert isinstance(bit_vector.field_type, SignedFixedPoint) 

265 assert bit_vector.field_type.max_bit_index == 7 

266 assert bit_vector.field_type.min_bit_index == -2 

267 

268 bit_vector = BitVector( 

269 name="", 

270 base_index=0, 

271 description="", 

272 width=4, 

273 default_value="1111", 

274 field_type=UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2), 

275 ) 

276 assert isinstance(bit_vector.field_type, UnsignedFixedPoint) 

277 assert bit_vector.field_type.max_bit_index == 7 

278 assert bit_vector.field_type.min_bit_index == -2