Coverage for hdl_registers/test/unit/test_register_field_type.py: 100%
89 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-29 22:03 +0000
« 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# pylint: disable=protected-access
11# Third party libraries
12import pytest
14# First party libraries
15from hdl_registers.register_field_type import (
16 FieldType,
17 Signed,
18 SignedFixedPoint,
19 Unsigned,
20 UnsignedFixedPoint,
21)
24@pytest.mark.parametrize(
25 "field_type, bit_width, min_value, max_value",
26 [
27 (Unsigned(), 2, 0.0, 3),
28 (Unsigned(), 8, 0.0, 255),
29 (Signed(), 2, -2, 1),
30 (Signed(), 6, -32, 31),
31 (Signed(), 8, -128, 127),
32 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2, 0.0, 0.75),
33 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8, 0.0, 63.75),
34 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6, 0.0, 63),
35 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2, -0.5, 0.25),
36 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8, -32, 31.75),
37 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6, -32, 31),
38 ],
39)
40def test_min_max_zero(field_type, bit_width, min_value, max_value):
41 assert field_type.min_value(bit_width) == min_value
42 assert field_type.max_value(bit_width) == max_value
43 assert field_type.convert_to_unsigned_binary(bit_width, 0.0) == 0b0
46@pytest.mark.parametrize(
47 "field_type, bit_width",
48 [
49 (Unsigned(), 2),
50 (Unsigned(), 8),
51 (Signed(), 2),
52 (Signed(), 6),
53 (Signed(), 8),
54 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2),
55 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8),
56 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6),
57 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2),
58 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8),
59 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6),
60 ],
61)
62def test_zero_min_max_restore(field_type, bit_width):
63 value = 0
64 field_type._check_value_in_range(bit_width, value)
65 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
66 assert unsigned == 0x0
67 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
68 assert restored == value
70 value = field_type.min_value(bit_width)
71 field_type._check_value_in_range(bit_width, value)
72 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
73 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
74 assert restored == value
76 value = field_type.max_value(bit_width)
77 field_type._check_value_in_range(bit_width, value)
78 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
79 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
80 assert restored == value
83@pytest.mark.parametrize(
84 "field_type, bit_width",
85 [
86 (Unsigned(), 2),
87 (Unsigned(), 8),
88 (Signed(), 2),
89 (Signed(), 6),
90 (Signed(), 8),
91 (UnsignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2),
92 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8),
93 (UnsignedFixedPoint(max_bit_index=5, min_bit_index=0), 6),
94 (SignedFixedPoint(max_bit_index=-1, min_bit_index=-2), 2),
95 (SignedFixedPoint(max_bit_index=5, min_bit_index=-2), 8),
96 (SignedFixedPoint(max_bit_index=5, min_bit_index=0), 6),
97 ],
98)
99def test_out_of_range(field_type: FieldType, bit_width: int):
100 value = field_type.min_value(bit_width) - 0.00001
101 with pytest.raises(ValueError):
102 field_type._check_value_in_range(bit_width, value)
103 with pytest.raises(ValueError):
104 field_type.convert_to_unsigned_binary(bit_width, value)
106 value = field_type.max_value(bit_width) + 0.00001
107 with pytest.raises(ValueError):
108 field_type._check_value_in_range(bit_width, value)
109 with pytest.raises(ValueError):
110 field_type.convert_to_unsigned_binary(bit_width, value)
113@pytest.mark.parametrize(
114 "bit_width, value, expected",
115 [
116 (8, 1, 0b00000001),
117 (8, -1, 0b11111111),
118 (8, 40, 0b00101000),
119 (8, -40, 0b11011000),
120 (8, 126, 0b01111110),
121 (8, -126, 0b10000010),
122 ],
123)
124def test_singed(bit_width, value, expected):
125 field_type = Signed()
126 field_type._check_value_in_range(bit_width, value)
127 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
128 assert unsigned == expected
129 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
130 assert restored == value
133@pytest.mark.parametrize(
134 "bit_width, max_bit_index, min_bit_index, value, exp_uint, exp_return",
135 [
136 (1, -1, -1, 0.00, 0b0, 0.00),
137 (1, -1, -1, 0.25, 0b0, 0.00),
138 (1, -1, -1, 0.50, 0b1, 0.50),
139 (2, -1, -2, 0.00, 0b00, 0.00),
140 (2, -1, -2, 0.25, 0b01, 0.25),
141 (2, -1, -2, 0.50, 0b10, 0.50),
142 (2, -1, -2, 0.75, 0b11, 0.75),
143 (2, -1, -2, 0.125, 0b000, 0.00),
144 (3, -1, -3, 0.125, 0b001, 0.125),
145 (4, 0, -3, 1.125, 0b1001, 1.125),
146 (9, 4, -4, 9.75, 0b010011100, 9.75),
147 (7, 3, -3, 4.625, 0b0100101, 4.625),
148 (2, 9, 8, 256.0, 0b01, 256.0),
149 (2, 9, 8, 768.0, 0b11, 768.0),
150 (2, -2, -3, 0.375, 0b11, 0.375),
151 (2, -3, -4, 0.1875, 0b11, 0.1875),
152 (10, 4, -5, 6.5, 0b0011010000, 6.5),
153 ],
154)
155def test_ufixed(bit_width, max_bit_index, min_bit_index, value, exp_uint, exp_return):
156 field_type = UnsignedFixedPoint(max_bit_index=max_bit_index, min_bit_index=min_bit_index)
157 field_type._check_value_in_range(bit_width, value)
158 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
159 assert unsigned == exp_uint
160 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
161 assert restored == exp_return
164@pytest.mark.parametrize(
165 "bit_width, max_bit_index, min_bit_index, value, expected",
166 [
167 (2, -1, -2, -0.25, 0b11),
168 (2, -1, -2, 0.25, 0b01),
169 (9, 4, -4, 9.75, 0b010011100),
170 (10, 5, -4, -13.8125, 0b1100100011),
171 (2, 9, 8, 256.0, 0b01),
172 (2, 9, 8, -256.0, 0b11),
173 (2, -2, -3, -0.125, 0b11),
174 (2, -3, -4, -0.0625, 0b11),
175 (10, 4, -5, -6.5, 0b1100110000),
176 ],
177)
178def test_sfixed(bit_width, max_bit_index, min_bit_index, value, expected):
179 field_type = SignedFixedPoint(max_bit_index=max_bit_index, min_bit_index=min_bit_index)
180 field_type._check_value_in_range(bit_width, value)
181 unsigned = field_type.convert_to_unsigned_binary(bit_width, value)
182 assert unsigned == expected
183 restored = field_type.convert_from_unsigned_binary(bit_width, unsigned)
184 assert restored == value
187@pytest.mark.parametrize(
188 "field_type_class, integer_bit_width, fraction_bit_width",
189 [
190 (UnsignedFixedPoint, 9, 2),
191 (UnsignedFixedPoint, 11, -8),
192 (UnsignedFixedPoint, -1, 3),
193 (SignedFixedPoint, 9, 2),
194 (SignedFixedPoint, 11, -8),
195 (SignedFixedPoint, -1, 3),
196 ],
197)
198def test_via_bit_widths(field_type_class, integer_bit_width, fraction_bit_width):
199 field_type = field_type_class.from_bit_widths(
200 integer_bit_width=integer_bit_width, fraction_bit_width=fraction_bit_width
201 )
202 assert field_type.integer_bit_width == integer_bit_width
203 assert field_type.fraction_bit_width == fraction_bit_width
206@pytest.mark.parametrize(
207 "field_type, bit_width, raise_valueerror",
208 [
209 (Unsigned(), 8, False),
210 (Unsigned(), 16, False),
211 (Signed(), 8, False),
212 (Signed(), 16, False),
213 (UnsignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 16, False),
214 (SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 16, False),
215 (UnsignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 32, True),
216 (SignedFixedPoint.from_bit_widths(integer_bit_width=8, fraction_bit_width=8), 32, True),
217 ],
218)
219def test_vhdl_typedef(field_type, bit_width, raise_valueerror):
220 if raise_valueerror:
221 with pytest.raises(ValueError):
222 field_type.vhdl_typedef(bit_width=bit_width)
223 else:
224 vhdl_str = field_type.vhdl_typedef(bit_width=bit_width)
225 assert "downto" in vhdl_str
228def test_repr():
229 unsigned0 = Unsigned()
230 unsigned1 = Unsigned()
231 signed0 = Signed()
232 signed1 = Signed()
233 ufixed0 = UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2)
234 ufixed1 = UnsignedFixedPoint(max_bit_index=7, min_bit_index=-2)
235 ufixed2 = UnsignedFixedPoint(max_bit_index=8, min_bit_index=-2)
236 sfixed0 = SignedFixedPoint(max_bit_index=7, min_bit_index=-2)
237 sfixed1 = SignedFixedPoint(max_bit_index=7, min_bit_index=-2)
238 sfixed2 = SignedFixedPoint(max_bit_index=8, min_bit_index=-2)
240 assert repr(unsigned0) == repr(unsigned1)
241 assert repr(signed0) == repr(signed1)
242 assert repr(ufixed0) == repr(ufixed1) != repr(ufixed2)
243 assert repr(sfixed0) == repr(sfixed1) != repr(sfixed2)
244 assert repr(ufixed0) != repr(sfixed0) != repr(ufixed0) != repr(sfixed0)