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

114 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-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/tsfpga/hdl_registers 

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

9 

10import pytest 

11 

12from hdl_registers.bit_vector import BitVector 

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

14 

15 

16def test_get_value(): 

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

18 

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

20 assert bit.get_value(register_value) == 0 

21 

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

23 assert bit.get_value(register_value) == 15 

24 

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

26 assert bit.get_value(register_value) == 5 

27 

28 # Test field_type 

29 field = BitVector( 

30 name="", 

31 base_index=2, 

32 description="", 

33 width=16, 

34 default_value="0" * 16, 

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

36 ) 

37 register_value = 0b11111111_00000011_11111111_11111100 

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

39 

40 

41def test_max_binary_value(): 

42 bit_vector = BitVector( 

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

44 ) 

45 assert bit_vector.max_binary_value == 0b11 

46 

47 bit_vector = BitVector( 

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

49 ) 

50 assert bit_vector.max_binary_value == 0b11111111_11111111_11111111_11111111 

51 

52 # Test with base_index > 0 

53 bit_vector = BitVector( 

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

55 ) 

56 assert bit_vector.max_binary_value == 0b1111 

57 

58 

59def test_set_value(): 

60 bit_vector = BitVector( 

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

62 ) 

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

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

65 

66 with pytest.raises(ValueError): 

67 bit_vector.set_value(0b111) 

68 

69 bit_vector = BitVector( 

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

71 ) 

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

73 

74 bit_vector = BitVector( 

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

76 ) 

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

78 

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

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

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

82 

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

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

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

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

87 assert value0 | value1 | value2 == register_value 

88 

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

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

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

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

93 assert value0 | value1 | value2 == register_value 

94 

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

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

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

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

99 assert value0 | value1 | value2 == register_value 

100 

101 # Test field_type 

102 field = BitVector( 

103 name="", 

104 base_index=2, 

105 description="", 

106 width=16, 

107 default_value="0" * 16, 

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

109 ) 

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

111 

112 

113def test_repr(): 

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

115 assert "apa" in repr( 

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

117 ) 

118 

119 # Different name 

120 assert repr( 

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

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

123 

124 # Different base_index 

125 assert repr( 

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

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

128 

129 # Different description 

130 assert repr( 

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

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

133 

134 # Different width 

135 assert repr( 

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

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

138 

139 # Different default_value 

140 assert repr( 

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

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

143 

144 # Different field_type 

145 field0 = BitVector( 

146 name="apa", 

147 base_index=0, 

148 description="", 

149 width=8, 

150 default_value="0" * 8, 

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

152 ) 

153 field1 = BitVector( 

154 name="apa", 

155 base_index=0, 

156 description="", 

157 width=8, 

158 default_value="0" * 8, 

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

160 ) 

161 field2 = BitVector( 

162 name="apa", 

163 base_index=0, 

164 description="", 

165 width=8, 

166 default_value="0" * 8, 

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

168 ) 

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

170 

171 

172def test_invalid_width(): 

173 with pytest.raises(ValueError) as exception_info: 

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

175 assert ( 

176 str(exception_info.value) 

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

178 ) 

179 

180 with pytest.raises(ValueError) as exception_info: 

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

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

183 

184 with pytest.raises(ValueError) as exception_info: 

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

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

187 

188 

189def test_invalid_default_value_should_raise_exception(): 

190 with pytest.raises(ValueError) as exception_info: 

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

192 assert str(exception_info.value) == ( 

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

194 ) 

195 

196 with pytest.raises(ValueError) as exception_info: 

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

198 assert str(exception_info.value) == ( 

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

200 ) 

201 

202 with pytest.raises(ValueError) as exception_info: 

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

204 assert str(exception_info.value) == ( 

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

206 ) 

207 

208 

209def test_can_update_default_value(): 

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

211 assert bit_vector.default_value == "1111" 

212 

213 bit_vector.default_value = "0000" 

214 assert bit_vector.default_value == "0000" 

215 

216 

217def test_updating_to_invalid_default_value_should_raise_exception(): 

218 # Create with a valid default_value 

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

220 

221 # Update to an invalid value 

222 with pytest.raises(ValueError) as exception_info: 

223 bit_vector.default_value = 1111 

224 assert str(exception_info.value) == ( 

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

226 ) 

227 

228 

229def test_default_value_uint(): 

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

231 assert bit_vector.default_value_uint == 0 

232 

233 bit_vector.default_value = "0010" 

234 assert bit_vector.default_value_uint == 2 

235 

236 bit_vector.default_value = "1001" 

237 assert bit_vector.default_value_uint == 9 

238 

239 

240def test_field_type(): 

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

242 assert isinstance(bit_vector.field_type, Unsigned) 

243 

244 bit_vector = BitVector( 

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

246 ) 

247 assert isinstance(bit_vector.field_type, Unsigned) 

248 

249 bit_vector = BitVector( 

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

251 ) 

252 assert isinstance(bit_vector.field_type, Signed) 

253 

254 bit_vector = BitVector( 

255 name="", 

256 base_index=0, 

257 description="", 

258 width=4, 

259 default_value="1111", 

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

261 ) 

262 assert isinstance(bit_vector.field_type, SignedFixedPoint) 

263 assert bit_vector.field_type.max_bit_index == 7 

264 assert bit_vector.field_type.min_bit_index == -2 

265 

266 bit_vector = BitVector( 

267 name="", 

268 base_index=0, 

269 description="", 

270 width=4, 

271 default_value="1111", 

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

273 ) 

274 assert isinstance(bit_vector.field_type, UnsignedFixedPoint) 

275 assert bit_vector.field_type.max_bit_index == 7 

276 assert bit_vector.field_type.min_bit_index == -2