Coverage for hdl_registers/generator/python/test/accessor/conftest.py: 100%
56 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 20:51 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 20:51 +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# --------------------------------------------------------------------------------------------------
10# Standard libraries
11from pathlib import Path
12from typing import Union
14# Third party libraries
15import pytest
16from tsfpga.system_utils import load_python_module
18# First party libraries
19from hdl_registers.field.numerical_interpretation import (
20 Signed,
21 SignedFixedPoint,
22 Unsigned,
23 UnsignedFixedPoint,
24)
25from hdl_registers.generator.python.accessor import PythonAccessorGenerator
26from hdl_registers.generator.python.pickle import PythonPickleGenerator
27from hdl_registers.register_array import RegisterArray
28from hdl_registers.register_list import RegisterList
29from hdl_registers.register_mode import RegisterMode
30from hdl_registers.register_modes import REGISTER_MODES
32# False positive for pytest fixtures
33# pylint: disable=redefined-outer-name
36@pytest.fixture(scope="session")
37def tmp_session_path(tmp_path_factory: pytest.TempdirFactory) -> Path:
38 """
39 tmp_path that is common for all test runs in this session.
40 Unlike the default tmp_path fixture, which is function scoped.
41 https://stackoverflow.com/questions/70779045
42 https://docs.pytest.org/en/6.2.x/tmpdir.html#the-tmp-path-factory-fixture
43 """
44 return tmp_path_factory.mktemp("temp")
47@pytest.fixture(scope="session")
48def generate_default_accessor(tmp_session_path):
49 """
50 Since all the tests use the same register list, we can save a lot of time by generating the
51 Python code artifact only once.
52 We run a huge amount of tests for the accessor, and the file generation takes 0.5-1 second,
53 so the gain is significant.
54 """
55 register_list = RegisterList(name="test")
57 add_test_registers(register_list_or_array=register_list)
58 add_empty_registers(register_list_or_array=register_list)
59 add_single_field_registers(register_list_or_array=register_list)
61 register_array = register_list.append_register_array(
62 name="reg_array_a", length=3, description=""
63 )
64 add_test_registers(register_list_or_array=register_array)
65 add_empty_registers(register_list_or_array=register_array)
66 add_single_field_registers(register_list_or_array=register_array)
68 PythonPickleGenerator(register_list=register_list, output_folder=tmp_session_path).create()
69 PythonAccessorGenerator(register_list=register_list, output_folder=tmp_session_path).create()
71 python_module = load_python_module(tmp_session_path / "test_accessor.py")
73 return tmp_session_path, python_module
76def add_test_registers(register_list_or_array: Union[RegisterList, RegisterArray]) -> None:
77 for mode in REGISTER_MODES.values():
78 setup_test_register(register_list_or_array=register_list_or_array, mode=mode)
81def setup_test_register(
82 register_list_or_array: Union[RegisterList, RegisterArray], mode: RegisterMode
83) -> None:
84 register = register_list_or_array.append_register(
85 f"reg_{mode.shorthand}", mode=mode, description=""
86 )
88 register.append_bit(name="bit_aa0", description="", default_value="0")
89 register.append_bit(name="bit_aa1", description="", default_value="1")
91 register.append_bit_vector(
92 name="unsigned_aa",
93 description="",
94 width=4,
95 default_value="0101",
96 numerical_interpretation=Unsigned(bit_width=4),
97 )
98 register.append_bit_vector(
99 name="signed_aa",
100 description="",
101 width=4,
102 default_value="1010",
103 numerical_interpretation=Signed(bit_width=4),
104 )
105 register.append_bit_vector(
106 name="ufixed_aa",
107 description="",
108 width=4,
109 default_value="0110",
110 numerical_interpretation=UnsignedFixedPoint(1, -2),
111 )
112 register.append_bit_vector(
113 name="sfixed_aa",
114 description="",
115 width=4,
116 default_value="1001",
117 numerical_interpretation=SignedFixedPoint(0, -3),
118 )
120 register.append_enumeration(
121 name="enumeration_aa",
122 description="",
123 elements=dict(element_aa0="", element_aa1="", element_aa2=""),
124 default_value="element_aa1",
125 )
127 register.append_integer(
128 name="uint_aa", description="", min_value=0, max_value=10, default_value=5
129 )
130 register.append_integer(
131 name="sint_aa", description="", min_value=-10, max_value=10, default_value=2
132 )
135def add_empty_registers(register_list_or_array: Union[RegisterList, RegisterArray]) -> None:
136 for mode in REGISTER_MODES.values():
137 register_list_or_array.append_register(
138 name=f"empty_{mode.shorthand}", mode=mode, description=""
139 )
142def add_single_field_registers(register_list_or_array: Union[RegisterList, RegisterArray]) -> None:
143 register = register_list_or_array.append_register(
144 "single_w_bit", mode=REGISTER_MODES["w"], description=""
145 )
146 register.append_bit(name="bit_bb", description="", default_value="1")
148 register = register_list_or_array.append_register(
149 "single_w_unsigned", mode=REGISTER_MODES["w"], description=""
150 )
151 register.append_bit_vector(
152 name="unsigned_bb",
153 description="",
154 width=4,
155 default_value="1011",
156 numerical_interpretation=Unsigned(bit_width=4),
157 )
159 register = register_list_or_array.append_register(
160 "single_r_w_sfixed", mode=REGISTER_MODES["r_w"], description=""
161 )
162 register.append_bit_vector(
163 name="sfixed_bb",
164 description="",
165 width=4,
166 default_value="1100",
167 numerical_interpretation=SignedFixedPoint(1, -2),
168 )
170 register = register_list_or_array.append_register(
171 "single_wpulse_enumeration", mode=REGISTER_MODES["wpulse"], description=""
172 )
173 register.append_enumeration(
174 name="enumeration_bb",
175 description="",
176 elements=dict(element_bb0="", element_bb1="", element_bb2=""),
177 default_value="element_bb2",
178 )
180 register = register_list_or_array.append_register(
181 "single_r_wpulse_uint", mode=REGISTER_MODES["r_wpulse"], description=""
182 )
183 register.append_integer(
184 name="uint_bb", description="", min_value=10, max_value=15, default_value=15
185 )