Coverage for hdl_registers/generator/vhdl/test/test_register_package.py: 100%
86 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# --------------------------------------------------------------------------------------------------
10"""
11Some limited unit tests that check the generated code.
12Note that the generated VHDL code is also simulated in a functional test.
13"""
15import pytest
16from tsfpga.system_utils import read_file
18from hdl_registers import HDL_REGISTERS_TESTS
19from hdl_registers.field.numerical_interpretation import (
20 Signed,
21 SignedFixedPoint,
22 Unsigned,
23 UnsignedFixedPoint,
24)
25from hdl_registers.generator.vhdl.register_package import VhdlRegisterPackageGenerator
26from hdl_registers.parser.toml import from_toml
27from hdl_registers.register_list import RegisterList
28from hdl_registers.register_modes import REGISTER_MODES
31def get_package(register_list, output_folder):
32 return read_file(VhdlRegisterPackageGenerator(register_list, output_folder).create())
35class RegisterConfigurationTest:
36 def __init__(self, name, source_toml_file):
37 self.register_list = from_toml(name=name, toml_file=source_toml_file)
39 self.register_list.add_constant(name="boolean_constant", value=True, description="")
40 self.register_list.add_constant(name="integer_constant", value=3, description="")
41 self.register_list.add_constant(name="real_constant", value=3.14, description="")
42 self.register_list.add_constant(name="real_big_constant", value=1e20, description="")
43 self.register_list.add_constant(name="real_small_constant", value=4e-8, description="")
44 self.register_list.add_constant(name="string_constant", value="apa", description="")
46 def test_vhdl_package(self, output_path, test_registers, test_constants):
47 vhdl = get_package(register_list=self.register_list, output_folder=output_path)
49 if test_registers:
50 assert "constant test_register_map : " in vhdl, vhdl
51 else:
52 assert "constant test_register_map : " not in vhdl, vhdl
54 if test_constants:
55 assert "constant test_constant_boolean_constant : boolean := true;" in vhdl, vhdl
56 assert "constant test_constant_integer_constant : integer := 3;" in vhdl, vhdl
57 assert "constant test_constant_real_constant : real := 3.14;" in vhdl, vhdl
58 assert "constant test_constant_real_big_constant : real := 1.0e+20;" in vhdl, vhdl
59 assert "constant test_constant_real_small_constant : real := 4.0e-08;" in vhdl, vhdl
60 assert 'constant test_constant_string_constant : string := "apa";' in vhdl, vhdl
61 assert (
62 "constant test_constant_base_address_hex : "
63 'unsigned(36 - 1 downto 0) := x"8_0000_0000";' in vhdl
64 ), vhdl
65 assert (
66 "constant test_constant_base_address_bin : "
67 'unsigned(36 - 1 downto 0) := "100000000000000000000000000000000000";' in vhdl
68 ), vhdl
69 else:
70 assert "boolean_constant" not in vhdl, vhdl
71 assert "integer_constant" not in vhdl, vhdl
72 assert "real_constant" not in vhdl, vhdl
73 assert "string_constant" not in vhdl, vhdl
76@pytest.fixture
77def register_configuration():
78 return RegisterConfigurationTest("test", HDL_REGISTERS_TESTS / "regs_test.toml")
81def test_vhdl_package_with_registers_and_constants(tmp_path, register_configuration):
82 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=True)
85def test_vhdl_package_with_registers_and_no_constants(tmp_path, register_configuration):
86 register_configuration.register_list.constants = []
87 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=False)
90def test_vhdl_package_with_constants_and_no_registers(tmp_path, register_configuration):
91 register_configuration.register_list.register_objects = []
92 register_configuration.test_vhdl_package(tmp_path, test_registers=False, test_constants=True)
95def test_vhdl_package_with_only_one_register(tmp_path):
96 """
97 Test that register_map constant has valid VHDL syntax even when there is only one register.
98 """
99 register_list = RegisterList(name="apa", source_definition_file=None)
100 register_list.append_register(
101 name="hest", mode=REGISTER_MODES["r"], description="a single register"
102 )
103 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create())
105 expected = """
106 constant apa_register_map : register_definition_vec_t(apa_register_range) := (
107 0 => (index => apa_hest, mode => r, utilized_width => 32)
108 );
110 constant apa_regs_init : apa_regs_t := (
111 0 => "00000000000000000000000000000000"
112 );
113"""
114 assert expected in vhdl, vhdl
117def test_vhdl_typedef(tmp_path):
118 register_list = RegisterList(name="test", source_definition_file=None)
119 register = register_list.append_register("number", REGISTER_MODES["r_w"], "")
121 register.append_bit_vector(
122 name="u0",
123 description="",
124 width=2,
125 default_value="11",
126 numerical_interpretation=Unsigned(bit_width=2),
127 )
129 register.append_bit_vector(
130 name="s0",
131 description="",
132 width=2,
133 default_value="11",
134 numerical_interpretation=Signed(bit_width=2),
135 )
137 register.append_bit_vector(
138 name="ufixed0",
139 description="",
140 width=2,
141 default_value="11",
142 numerical_interpretation=UnsignedFixedPoint(-1, -2),
143 )
144 register.append_bit_vector(
145 name="ufixed1",
146 description="",
147 width=8,
148 default_value="1" * 8,
149 numerical_interpretation=UnsignedFixedPoint(5, -2),
150 )
152 register.append_bit_vector(
153 name="sfixed0",
154 description="",
155 width=2,
156 default_value="11",
157 numerical_interpretation=SignedFixedPoint(-1, -2),
158 )
159 register.append_bit_vector(
160 name="sfixed1",
161 description="",
162 width=6,
163 default_value="1" * 6,
164 numerical_interpretation=SignedFixedPoint(5, 0),
165 )
167 register.append_integer(
168 name="integer0", description="", min_value=1, max_value=3, default_value=2
169 )
171 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create())
173 assert "subtype test_number_u0_t is u_unsigned(1 downto 0);" in vhdl, vhdl
175 assert "subtype test_number_s0_t is u_signed(1 downto 0);" in vhdl, vhdl
177 assert "subtype test_number_ufixed0_t is ufixed(-1 downto -2);" in vhdl, vhdl
178 assert "subtype test_number_ufixed1_t is ufixed(5 downto -2);" in vhdl, vhdl
180 assert "subtype test_number_sfixed0_t is sfixed(-1 downto -2);" in vhdl, vhdl
181 assert "subtype test_number_sfixed1_t is sfixed(5 downto 0);" in vhdl, vhdl
183 assert "subtype test_number_integer0_t is integer range 1 to 3;" in vhdl, vhdl
186def test_address_width(tmp_path):
187 register_list = RegisterList(name="apa", source_definition_file=None)
188 constant_name = "apa_address_width"
190 def check(num_addressing_bits):
191 assert f"{constant_name} : positive := {num_addressing_bits + 2}" in get_package(
192 register_list, tmp_path
193 )
195 assert constant_name not in get_package(register_list, tmp_path)
197 register_list.append_register("a", REGISTER_MODES["r"], "")
198 check(1)
200 register_list.append_register("b", REGISTER_MODES["r"], "")
201 check(1)
203 register_list.append_register("c", REGISTER_MODES["r"], "")
204 check(2)
206 register_list.append_register_array("d", 2, "").append_register("e", REGISTER_MODES["r"], "")
207 check(3)