Coverage for hdl_registers/generator/vhdl/test/test_register_package.py: 100%
86 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 20:51 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 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"""
11Some limited unit tests that check the generated code.
12Note that the generated VHDL code is also simulated in a functional test.
13"""
15# Third party libraries
16import pytest
17from tsfpga.system_utils import read_file
19# First party libraries
20from hdl_registers import HDL_REGISTERS_TESTS
21from hdl_registers.field.numerical_interpretation import (
22 Signed,
23 SignedFixedPoint,
24 Unsigned,
25 UnsignedFixedPoint,
26)
27from hdl_registers.generator.vhdl.register_package import VhdlRegisterPackageGenerator
28from hdl_registers.parser.toml import from_toml
29from hdl_registers.register_list import RegisterList
30from hdl_registers.register_modes import REGISTER_MODES
33def get_package(register_list, output_folder):
34 return read_file(VhdlRegisterPackageGenerator(register_list, output_folder).create())
37class RegisterConfigurationTest:
38 def __init__(self, name, source_toml_file):
39 self.register_list = from_toml(name=name, toml_file=source_toml_file)
41 self.register_list.add_constant(name="boolean_constant", value=True, description="")
42 self.register_list.add_constant(name="integer_constant", value=3, description="")
43 self.register_list.add_constant(name="real_constant", value=3.14, description="")
44 self.register_list.add_constant(name="real_big_constant", value=1e20, description="")
45 self.register_list.add_constant(name="real_small_constant", value=4e-8, description="")
46 self.register_list.add_constant(name="string_constant", value="apa", description="")
48 def test_vhdl_package(self, output_path, test_registers, test_constants):
49 vhdl = get_package(register_list=self.register_list, output_folder=output_path)
51 if test_registers:
52 assert "constant test_register_map : " in vhdl, vhdl
53 else:
54 assert "constant test_register_map : " not in vhdl, vhdl
56 if test_constants:
57 assert "constant test_constant_boolean_constant : boolean := true;" in vhdl, vhdl
58 assert "constant test_constant_integer_constant : integer := 3;" in vhdl, vhdl
59 assert "constant test_constant_real_constant : real := 3.14;" in vhdl, vhdl
60 assert "constant test_constant_real_big_constant : real := 1.0e+20;" in vhdl, vhdl
61 assert "constant test_constant_real_small_constant : real := 4.0e-08;" in vhdl, vhdl
62 assert 'constant test_constant_string_constant : string := "apa";' in vhdl, vhdl
63 assert (
64 "constant test_constant_base_address_hex : "
65 'unsigned(36 - 1 downto 0) := x"8_0000_0000";' in vhdl
66 ), vhdl
67 assert (
68 "constant test_constant_base_address_bin : "
69 'unsigned(36 - 1 downto 0) := "100000000000000000000000000000000000";' in vhdl
70 ), vhdl
71 else:
72 assert "boolean_constant" not in vhdl, vhdl
73 assert "integer_constant" not in vhdl, vhdl
74 assert "real_constant" not in vhdl, vhdl
75 assert "string_constant" not in vhdl, vhdl
78@pytest.fixture
79def register_configuration():
80 return RegisterConfigurationTest("test", HDL_REGISTERS_TESTS / "regs_test.toml")
83# False positive for pytest fixtures
84# pylint: disable=redefined-outer-name
87def test_vhdl_package_with_registers_and_constants(tmp_path, register_configuration):
88 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=True)
91def test_vhdl_package_with_registers_and_no_constants(tmp_path, register_configuration):
92 register_configuration.register_list.constants = []
93 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=False)
96def test_vhdl_package_with_constants_and_no_registers(tmp_path, register_configuration):
97 register_configuration.register_list.register_objects = []
98 register_configuration.test_vhdl_package(tmp_path, test_registers=False, test_constants=True)
101def test_vhdl_package_with_only_one_register(tmp_path):
102 """
103 Test that register_map constant has valid VHDL syntax even when there is only one register.
104 """
105 register_list = RegisterList(name="apa", source_definition_file=None)
106 register_list.append_register(
107 name="hest", mode=REGISTER_MODES["r"], description="a single register"
108 )
109 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create())
111 expected = """
112 constant apa_register_map : register_definition_vec_t(apa_register_range) := (
113 0 => (index => apa_hest, mode => r, utilized_width => 32)
114 );
116 constant apa_regs_init : apa_regs_t := (
117 0 => "00000000000000000000000000000000"
118 );
119"""
120 assert expected in vhdl, vhdl
123def test_vhdl_typedef(tmp_path):
124 register_list = RegisterList(name="test", source_definition_file=None)
125 register = register_list.append_register("number", REGISTER_MODES["r_w"], "")
127 register.append_bit_vector(
128 name="u0",
129 description="",
130 width=2,
131 default_value="11",
132 numerical_interpretation=Unsigned(bit_width=2),
133 )
135 register.append_bit_vector(
136 name="s0",
137 description="",
138 width=2,
139 default_value="11",
140 numerical_interpretation=Signed(bit_width=2),
141 )
143 register.append_bit_vector(
144 name="ufixed0",
145 description="",
146 width=2,
147 default_value="11",
148 numerical_interpretation=UnsignedFixedPoint(-1, -2),
149 )
150 register.append_bit_vector(
151 name="ufixed1",
152 description="",
153 width=8,
154 default_value="1" * 8,
155 numerical_interpretation=UnsignedFixedPoint(5, -2),
156 )
158 register.append_bit_vector(
159 name="sfixed0",
160 description="",
161 width=2,
162 default_value="11",
163 numerical_interpretation=SignedFixedPoint(-1, -2),
164 )
165 register.append_bit_vector(
166 name="sfixed1",
167 description="",
168 width=6,
169 default_value="1" * 6,
170 numerical_interpretation=SignedFixedPoint(5, 0),
171 )
173 register.append_integer(
174 name="integer0", description="", min_value=1, max_value=3, default_value=2
175 )
177 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create())
179 assert "subtype test_number_u0_t is u_unsigned(1 downto 0);" in vhdl, vhdl
181 assert "subtype test_number_s0_t is u_signed(1 downto 0);" in vhdl, vhdl
183 assert "subtype test_number_ufixed0_t is ufixed(-1 downto -2);" in vhdl, vhdl
184 assert "subtype test_number_ufixed1_t is ufixed(5 downto -2);" in vhdl, vhdl
186 assert "subtype test_number_sfixed0_t is sfixed(-1 downto -2);" in vhdl, vhdl
187 assert "subtype test_number_sfixed1_t is sfixed(5 downto 0);" in vhdl, vhdl
189 assert "subtype test_number_integer0_t is integer range 1 to 3;" in vhdl, vhdl
192def test_address_width(tmp_path):
193 register_list = RegisterList(name="apa", source_definition_file=None)
194 constant_name = "apa_address_width"
196 def check(num_addressing_bits):
197 assert f"{constant_name} : positive := {num_addressing_bits + 2}" in get_package(
198 register_list, tmp_path
199 )
201 assert constant_name not in get_package(register_list, tmp_path)
203 register_list.append_register("a", REGISTER_MODES["r"], "")
204 check(1)
206 register_list.append_register("b", REGISTER_MODES["r"], "")
207 check(1)
209 register_list.append_register("c", REGISTER_MODES["r"], "")
210 check(2)
212 register_list.append_register_array("d", 2, "").append_register("e", REGISTER_MODES["r"], "")
213 check(3)