Coverage for hdl_registers/parser/test/test_parser/test_data_file_format_convert.py: 100%
35 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# --------------------------------------------------------------------------------------------------
11import pytest
12from tsfpga.system_utils import create_file
14from hdl_registers.parser.json import _load_json_file, from_json
15from hdl_registers.parser.toml import _load_toml_file, from_toml
16from hdl_registers.parser.yaml import _load_yaml_file, from_yaml
19def test_convert_big_toml_file(tmp_path):
20 toml_path = create_file(
21 file=tmp_path / "regs.toml",
22 contents="""
23################################################################################
24[register.data]
26mode = "w"
29################################################################################
30[register.status]
32mode = "r_w"
33description = "Status register"
35[register.status.bit.bad]
37description = "Bad things happen"
39[register.status.enumeration.direction]
41description = "The direction mode"
42default_value = "input"
44element.passthrough = ""
45element.input = ""
46element.output = "use in output mode"
48[register.status.bit.not_good]
50description = ""
51default_value = "1"
53[register.status.bit_vector.interrupts]
55width = 4
56description = "Many interrupts"
57default_value = "0110"
59[register.status.integer.count]
61description = "The number of things"
62min_value = -5
63max_value = 15
66################################################################################
67[register_array.config]
69array_length = 3
70description = "A register array"
72# ------------------------------------------------------------------------------
73[register_array.config.register.input_settings]
75description = "Input configuration"
76mode = "r_w"
78[register_array.config.register.input_settings.bit.enable]
80description = "Enable things"
81default_value = "1"
83[register_array.config.register.input_settings.integer.number]
85description = "Configure number"
86max_value = 3
87default_value = 1
89[register_array.config.register.input_settings.bit.disable]
91description = ""
92default_value = "0"
94[register_array.config.register.input_settings.enumeration.size]
96element.small = ""
97element.large = ""
100# ------------------------------------------------------------------------------
101[register_array.config.register.output_settings]
103mode = "w"
105[register_array.config.register.output_settings.bit_vector.data]
107width=16
108description = "Some data"
109default_value="0000000000000011"
112################################################################################
113[constant.burst_length_beats]
115value = 256
118################################################################################
119[constant.data_mask]
121value = "0b1100_1111"
122data_type = "unsigned"
123""",
124 )
126 with pytest.raises(ValueError) as exception_info:
127 from_toml(name="", toml_file=toml_path)
128 assert str(exception_info.value) == ("Found register data in old format. See message above.")
130 new_toml_path = tmp_path / "regs_version_6_format.toml"
132 # Parsing of fixed file should pass without error.
133 from_toml(name="", toml_file=new_toml_path)
135 got = _load_toml_file(file_path=new_toml_path)
137 # Expected data in the new format.
138 # Note that the bit fields have been grouped together, and not in the order they appeared
139 # in the original TOML.
140 expected = {
141 "data": {"mode": "w"},
142 "status": {
143 "mode": "r_w",
144 "description": "Status register",
145 "bad": {"type": "bit", "description": "Bad things happen"},
146 "not_good": {"type": "bit", "description": "", "default_value": "1"},
147 "direction": {
148 "type": "enumeration",
149 "description": "The direction mode",
150 "default_value": "input",
151 "element": {"passthrough": "", "input": "", "output": "use in output mode"},
152 },
153 "interrupts": {
154 "type": "bit_vector",
155 "width": 4,
156 "description": "Many interrupts",
157 "default_value": "0110",
158 },
159 "count": {
160 "type": "integer",
161 "description": "The number of things",
162 "min_value": -5,
163 "max_value": 15,
164 },
165 },
166 "config": {
167 "type": "register_array",
168 "array_length": 3,
169 "description": "A register array",
170 "input_settings": {
171 "description": "Input configuration",
172 "mode": "r_w",
173 "enable": {"type": "bit", "description": "Enable things", "default_value": "1"},
174 "disable": {"type": "bit", "description": "", "default_value": "0"},
175 "number": {
176 "type": "integer",
177 "description": "Configure number",
178 "max_value": 3,
179 "default_value": 1,
180 },
181 "size": {"type": "enumeration", "element": {"small": "", "large": ""}},
182 },
183 "output_settings": {
184 "mode": "w",
185 "data": {
186 "type": "bit_vector",
187 "width": 16,
188 "description": "Some data",
189 "default_value": "0000000000000011",
190 },
191 },
192 },
193 "burst_length_beats": {"type": "constant", "value": 256},
194 "data_mask": {"type": "constant", "value": "0b1100_1111", "data_type": "unsigned"},
195 }
197 assert got == expected
200def test_convert_small_json_file(tmp_path):
201 json_path = create_file(
202 file=tmp_path / "regs.json",
203 contents="""
204{
205 "register": {
206 "apa": {
207 "mode": "r_w",
208 "description": "Apa.",
209 "bit": {
210 "enable": {
211 "description": "Enable.",
212 "default_value": "1"
213 }
214 }
215 },
216 "hest": {
217 "mode": "r",
218 "description": "Hest.",
219 "bit": {
220 "disable": {
221 "description": "Disable."
222 }
223 }
224 }
225 }
226}
227""",
228 )
230 with pytest.raises(ValueError) as exception_info:
231 from_json(name="", json_file=json_path)
232 assert str(exception_info.value) == ("Found register data in old format. See message above.")
234 new_json_path = tmp_path / "regs_version_6_format.json"
236 # Parsing of fixed file should pass without error.
237 from_json(name="", json_file=new_json_path)
239 got = _load_json_file(file_path=new_json_path)
240 expected = {
241 "apa": {
242 "mode": "r_w",
243 "description": "Apa.",
244 "enable": {"type": "bit", "description": "Enable.", "default_value": "1"},
245 },
246 "hest": {
247 "mode": "r",
248 "description": "Hest.",
249 "disable": {"type": "bit", "description": "Disable."},
250 },
251 }
253 assert got == expected
256def test_convert_small_yaml_file(tmp_path):
257 yaml_path = create_file(
258 file=tmp_path / "regs.yaml",
259 contents="""
260register:
261 apa:
262 mode: r_w
263 description: Apa.
264 bit:
265 enable:
266 default_value: '1'
267 description: Enable.
269 hest:
270 mode: r
271 description: Hest.
272 bit:
273 disable:
274 description: Disable.
275""",
276 )
278 with pytest.raises(ValueError) as exception_info:
279 from_yaml(name="", yaml_file=yaml_path)
280 assert str(exception_info.value) == ("Found register data in old format. See message above.")
282 new_yaml_path = tmp_path / "regs_version_6_format.yaml"
284 # Parsing of fixed file should pass without error.
285 from_yaml(name="", yaml_file=new_yaml_path)
287 got = _load_yaml_file(file_path=new_yaml_path)
288 expected = {
289 "apa": {
290 "mode": "r_w",
291 "description": "Apa.",
292 "enable": {"type": "bit", "description": "Enable.", "default_value": "1"},
293 },
294 "hest": {
295 "mode": "r",
296 "description": "Hest.",
297 "disable": {"type": "bit", "description": "Disable."},
298 },
299 }
301 assert got == expected