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

89 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# pylint: disable=protected-access 

10 

11import pytest 

12from hdl_registers.register_field_type import ( 

13 FieldType, 

14 Unsigned, 

15 Signed, 

16 SignedFixedPoint, 

17 UnsignedFixedPoint, 

18) 

19 

20 

21@pytest.mark.parametrize( 

22 "field_type, bit_width, min_value, max_value", 

23 [ 

24 (Unsigned(), 2, 0.0, 3), 

25 (Unsigned(), 8, 0.0, 255), 

26 (Signed(), 2, -2, 1), 

27 (Signed(), 6, -32, 31), 

28 (Signed(), 8, -128, 127), 

29 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2, 0.0, 0.75), 

30 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8, 0.0, 63.75), 

31 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6, 0.0, 63), 

32 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2, -0.5, 0.25), 

33 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8, -32, 31.75), 

34 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6, -32, 31), 

35 ], 

36) 

37def test_min_max_zero(field_type, bit_width, min_value, max_value): 

38 assert field_type.min_value(bit_width) == min_value 

39 assert field_type.max_value(bit_width) == max_value 

40 assert field_type.convert_to_unsigned_binary(bit_width, 0.0) == 0b0 

41 

42 

43@pytest.mark.parametrize( 

44 "field_type, bit_width", 

45 [ 

46 (Unsigned(), 2), 

47 (Unsigned(), 8), 

48 (Signed(), 2), 

49 (Signed(), 6), 

50 (Signed(), 8), 

51 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2), 

52 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8), 

53 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6), 

54 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2), 

55 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8), 

56 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6), 

57 ], 

58) 

59def test_zero_min_max_restore(field_type, bit_width): 

60 value = 0 

61 field_type._check_value_in_range(bit_width, value) 

62 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

63 assert unsigned == 0x0 

64 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

65 assert restored == value 

66 

67 value = field_type.min_value(bit_width) 

68 field_type._check_value_in_range(bit_width, value) 

69 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

70 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

71 assert restored == value 

72 

73 value = field_type.max_value(bit_width) 

74 field_type._check_value_in_range(bit_width, value) 

75 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

76 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

77 assert restored == value 

78 

79 

80@pytest.mark.parametrize( 

81 "field_type, bit_width", 

82 [ 

83 (Unsigned(), 2), 

84 (Unsigned(), 8), 

85 (Signed(), 2), 

86 (Signed(), 6), 

87 (Signed(), 8), 

88 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2), 

89 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8), 

90 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6), 

91 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2), 

92 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8), 

93 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6), 

94 ], 

95) 

96def test_out_of_range(field_type: FieldType, bit_width: int): 

97 value = field_type.min_value(bit_width) - 0.00001 

98 with pytest.raises(ValueError): 

99 field_type._check_value_in_range(bit_width, value) 

100 with pytest.raises(ValueError): 

101 field_type.convert_to_unsigned_binary(bit_width, value) 

102 

103 value = field_type.max_value(bit_width) + 0.00001 

104 with pytest.raises(ValueError): 

105 field_type._check_value_in_range(bit_width, value) 

106 with pytest.raises(ValueError): 

107 field_type.convert_to_unsigned_binary(bit_width, value) 

108 

109 

110@pytest.mark.parametrize( 

111 "bit_width, value, expected", 

112 [ 

113 (8, 1, 0b00000001), 

114 (8, -1, 0b11111111), 

115 (8, 40, 0b00101000), 

116 (8, -40, 0b11011000), 

117 (8, 126, 0b01111110), 

118 (8, -126, 0b10000010), 

119 ], 

120) 

121def test_singed(bit_width, value, expected): 

122 field_type = Signed() 

123 field_type._check_value_in_range(bit_width, value) 

124 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

125 assert unsigned == expected 

126 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

127 assert restored == value 

128 

129 

130@pytest.mark.parametrize( 

131 "bit_width, max_bit_index, min_bit_index, value, exp_uint, exp_return", 

132 [ 

133 (1, -1, -1, 0.00, 0b0, 0.00), 

134 (1, -1, -1, 0.25, 0b0, 0.00), 

135 (1, -1, -1, 0.50, 0b1, 0.50), 

136 (2, -1, -2, 0.00, 0b00, 0.00), 

137 (2, -1, -2, 0.25, 0b01, 0.25), 

138 (2, -1, -2, 0.50, 0b10, 0.50), 

139 (2, -1, -2, 0.75, 0b11, 0.75), 

140 (2, -1, -2, 0.125, 0b000, 0.00), 

141 (3, -1, -3, 0.125, 0b001, 0.125), 

142 (4, 0, -3, 1.125, 0b1001, 1.125), 

143 (9, 4, -4, 9.75, 0b010011100, 9.75), 

144 (7, 3, -3, 4.625, 0b0100101, 4.625), 

145 (2, 9, 8, 256.0, 0b01, 256.0), 

146 (2, 9, 8, 768.0, 0b11, 768.0), 

147 (2, -2, -3, 0.375, 0b11, 0.375), 

148 (2, -3, -4, 0.1875, 0b11, 0.1875), 

149 (10, 4, -5, 6.5, 0b0011010000, 6.5), 

150 ], 

151) 

152def test_ufixed(bit_width, max_bit_index, min_bit_index, value, exp_uint, exp_return): 

153 field_type = UnsignedFixedPoint(max_bit_index=max_bit_index, min_bit_index=min_bit_index) 

154 field_type._check_value_in_range(bit_width, value) 

155 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

156 assert unsigned == exp_uint 

157 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

158 assert restored == exp_return 

159 

160 

161@pytest.mark.parametrize( 

162 "bit_width, max_bit_index, min_bit_index, value, expected", 

163 [ 

164 (2, -1, -2, -0.25, 0b11), 

165 (2, -1, -2, 0.25, 0b01), 

166 (9, 4, -4, 9.75, 0b010011100), 

167 (10, 5, -4, -13.8125, 0b1100100011), 

168 (2, 9, 8, 256.0, 0b01), 

169 (2, 9, 8, -256.0, 0b11), 

170 (2, -2, -3, -0.125, 0b11), 

171 (2, -3, -4, -0.0625, 0b11), 

172 (10, 4, -5, -6.5, 0b1100110000), 

173 ], 

174) 

175def test_sfixed(bit_width, max_bit_index, min_bit_index, value, expected): 

176 field_type = SignedFixedPoint(max_bit_index=max_bit_index, min_bit_index=min_bit_index) 

177 field_type._check_value_in_range(bit_width, value) 

178 unsigned = field_type.convert_to_unsigned_binary(bit_width, value) 

179 assert unsigned == expected 

180 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned) 

181 assert restored == value 

182 

183 

184@pytest.mark.parametrize( 

185 "field_type_class, integer_bit_width, fraction_bit_width", 

186 [ 

187 (UnsignedFixedPoint, 9, 2), 

188 (UnsignedFixedPoint, 11, -8), 

189 (UnsignedFixedPoint, -1, 3), 

190 (SignedFixedPoint, 9, 2), 

191 (SignedFixedPoint, 11, -8), 

192 (SignedFixedPoint, -1, 3), 

193 ], 

194) 

195def test_via_bit_widths(field_type_class, integer_bit_width, fraction_bit_width): 

196 field_type = field_type_class.from_bit_widths( 

197 integer_bit_width=integer_bit_width, fraction_bit_width=fraction_bit_width 

198 ) 

199 assert field_type.integer_bit_width == integer_bit_width 

200 assert field_type.fraction_bit_width == fraction_bit_width 

201 

202 

203@pytest.mark.parametrize( 

204 "field_type, bit_width, raise_valueerror", 

205 [ 

206 (Unsigned(), 8, False), 

207 (Unsigned(), 16, False), 

208 (Signed(), 8, False), 

209 (Signed(), 16, False), 

210 (UnsignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 16, False), 

211 (SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 16, False), 

212 (UnsignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 32, True), 

213 (SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 32, True), 

214 ], 

215) 

216def test_vhdl_typedef(field_type, bit_width, raise_valueerror): 

217 if raise_valueerror: 

218 with pytest.raises(ValueError): 

219 field_type.vhdl_typedef(bit_width=bit_width) 

220 else: 

221 vhdl_str = field_type.vhdl_typedef(bit_width=bit_width) 

222 assert "downto" in vhdl_str 

223 

224 

225def test_repr(): 

226 unsigned0 = Unsigned() 

227 unsigned1 = Unsigned() 

228 signed0 = Signed() 

229 signed1 = Signed() 

230 ufixed0 = UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2) 

231 ufixed1 = UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2) 

232 ufixed2 = UnsignedFixedPoint(max_bit_index=8, min_bit_index=-2) 

233 sfixed0 = SignedFixedPoint(max_bit_index=7, min_bit_index=-2) 

234 sfixed1 = SignedFixedPoint(max_bit_index=7, min_bit_index=-2) 

235 sfixed2 = SignedFixedPoint(max_bit_index=8, min_bit_index=-2) 

236 

237 assert repr(unsigned0) == repr(unsigned1) 

238 assert repr(signed0) == repr(signed1) 

239 assert repr(ufixed0) == repr(ufixed1) != repr(ufixed2) 

240 assert repr(sfixed0) == repr(sfixed1) != repr(sfixed2) 

241 assert repr(ufixed0) != repr(sfixed0) != repr(ufixed0) != repr(sfixed0)