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