Coverage for hdl_registers/generator/vhdl/test/test_register_vhdl_generator.py: 100%
86 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 20:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 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# Standard libraries
16from pathlib import Path
18# Third party libraries
19from tsfpga.system_utils import read_file
21# First party libraries
22from hdl_registers.generator.vhdl.axi_lite.wrapper import VhdlAxiLiteWrapperGenerator
23from hdl_registers.generator.vhdl.record_package import VhdlRecordPackageGenerator
24from hdl_registers.generator.vhdl.register_package import VhdlRegisterPackageGenerator
25from hdl_registers.generator.vhdl.simulation.check_package import (
26 VhdlSimulationCheckPackageGenerator,
27)
28from hdl_registers.generator.vhdl.simulation.read_write_package import (
29 VhdlSimulationReadWritePackageGenerator,
30)
31from hdl_registers.generator.vhdl.simulation.wait_until_package import (
32 VhdlSimulationWaitUntilPackageGenerator,
33)
34from hdl_registers.register_list import RegisterList
35from hdl_registers.register_modes import REGISTER_MODES
38def generate_all_vhdl_artifacts(register_list: RegisterList, output_folder: Path) -> None:
39 VhdlRegisterPackageGenerator(
40 register_list=register_list, output_folder=output_folder
41 ).create_if_needed()
43 VhdlRecordPackageGenerator(
44 register_list=register_list, output_folder=output_folder
45 ).create_if_needed()
47 VhdlAxiLiteWrapperGenerator(
48 register_list=register_list, output_folder=output_folder
49 ).create_if_needed()
51 VhdlSimulationReadWritePackageGenerator(
52 register_list=register_list, output_folder=output_folder
53 ).create_if_needed()
55 VhdlSimulationCheckPackageGenerator(
56 register_list=register_list, output_folder=output_folder
57 ).create_if_needed()
59 VhdlSimulationWaitUntilPackageGenerator(
60 register_list=register_list, output_folder=output_folder
61 ).create_if_needed()
64def generate_strange_register_maps(output_path):
65 """
66 Generate register VHDL artifacts for some strange niche cases.
67 """
69 def create_packages(direction, mode):
70 def append_register(data, name):
71 """
72 Append a register with some fields.
73 """
74 register = data.append_register(
75 name=f"{name}_{mode.shorthand}", mode=mode, description=""
76 )
78 register.append_integer(
79 name="integer", description="", min_value=-10, max_value=10, default_value=3
80 )
81 register.append_enumeration(
82 name="enumeration", description="", elements=dict(a="", b=""), default_value="b"
83 )
85 def append_registers(data):
86 """
87 Append some registers with some fields, either to a RegisterList or a RegisterArray.
88 """
89 append_register(data=data, name="first")
90 append_register(data=data, name="second")
92 # Some plain registers, in one direction only.
93 register_list = RegisterList(name=f"plain_only_{direction}")
94 append_registers(data=register_list)
95 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path)
97 # Some register arrays, in one direction only.
98 register_list = RegisterList(name=f"array_only_{direction}")
99 register_array = register_list.append_register_array(name="apa", length=5, description="")
100 append_registers(data=register_array)
101 register_array = register_list.append_register_array(name="hest", length=10, description="")
102 append_registers(data=register_array)
103 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path)
105 # Plain registers and some register arrays, in one direction only.
106 register_list = RegisterList(name=f"plain_and_array_only_{direction}")
107 append_registers(data=register_list)
108 register_array = register_list.append_register_array(name="apa", length=5, description="")
109 append_registers(data=register_array)
110 register_array = register_list.append_register_array(name="hest", length=10, description="")
111 append_registers(data=register_array)
112 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path)
114 # Mode 'Read only' should give registers only in the 'up' direction'
115 create_packages(direction="up", mode=REGISTER_MODES["r"])
116 # Mode 'Write only' should give registers only in the 'down' direction'
117 create_packages(direction="down", mode=REGISTER_MODES["w"])
119 register_list = RegisterList(name="only_constants")
120 register_list.add_constant(name="first", value=123, description="")
121 register_list.add_constant(name="second", value=True, description="")
122 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path)
124 register_list = RegisterList(name="empty")
125 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path)
128def _get_register_arrays_record_string(direction):
129 return (
130 f"records for the registers of each register array the are in the '{direction}' direction"
131 )
134def test_registers_only_in_up_direction_should_give_no_down_type_or_port(tmp_path):
135 generate_strange_register_maps(output_path=tmp_path)
137 for file_name in ["array_only_up", "plain_and_array_only_up", "plain_only_up"]:
138 vhd = read_file(tmp_path / f"{file_name}_register_record_pkg.vhd")
140 assert f"{file_name}_regs_up_t" in vhd
141 assert f"{file_name}_regs_down_t" not in vhd
143 # If there are no arrays there should be no records for arrays, and this comment shall not
144 # be present.
145 string = _get_register_arrays_record_string("up")
146 if "array" in file_name:
147 assert string in vhd
148 else:
149 assert string not in vhd
151 # The 'down' comment shall never be present since we have no 'down' registers.
152 string = _get_register_arrays_record_string("down")
153 assert string not in vhd
155 vhd = read_file(tmp_path / f"{file_name}_reg_file.vhd")
157 assert "regs_up : in" in vhd
158 assert "regs_down : out" not in vhd
160 assert "reg_was_read : out" in vhd
161 assert "reg_was_written : out" not in vhd
164def test_registers_only_in_down_direction_should_give_no_down_type_or_port(tmp_path):
165 generate_strange_register_maps(output_path=tmp_path)
167 for file_name in ["array_only_down", "plain_and_array_only_down", "plain_only_down"]:
168 vhd = read_file(tmp_path / f"{file_name}_register_record_pkg.vhd")
170 assert f"{file_name}_regs_up_t" not in vhd
171 assert f"{file_name}_regs_down_t" in vhd
173 # If there are no arrays there should be no records for arrays, and this comment shall not
174 # be present.
175 string = _get_register_arrays_record_string("down")
176 if "array" in file_name:
177 assert string in vhd
178 else:
179 assert string not in vhd
181 # The 'up' comment shall never be present since we have no 'up' registers.
182 string = _get_register_arrays_record_string("up")
183 assert string not in vhd
185 vhd = read_file(tmp_path / f"{file_name}_reg_file.vhd")
187 assert "regs_up : in" not in vhd
188 assert "regs_down : out" in vhd
190 assert "reg_was_read : out" not in vhd
191 assert "reg_was_written : out" in vhd