Coverage for hdl_registers/parser/test/test_parser/test_data_file_format_convert.py: 100%
35 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 20:51 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 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# Standard libraries
12# Third party libraries
13import pytest
14from tsfpga.system_utils import create_file
16# First party libraries
17from hdl_registers.parser.json import _load_json_file, from_json
18from hdl_registers.parser.toml import _load_toml_file, from_toml
19from hdl_registers.parser.yaml import _load_yaml_file, from_yaml
22def test_convert_big_toml_file(tmp_path):
23 toml_path = create_file(
24 file=tmp_path / "regs.toml",
25 contents="""
26################################################################################
27[register.data]
29mode = "w"
32################################################################################
33[register.status]
35mode = "r_w"
36description = "Status register"
38[register.status.bit.bad]
40description = "Bad things happen"
42[register.status.enumeration.direction]
44description = "The direction mode"
45default_value = "input"
47element.passthrough = ""
48element.input = ""
49element.output = "use in output mode"
51[register.status.bit.not_good]
53description = ""
54default_value = "1"
56[register.status.bit_vector.interrupts]
58width = 4
59description = "Many interrupts"
60default_value = "0110"
62[register.status.integer.count]
64description = "The number of things"
65min_value = -5
66max_value = 15
69################################################################################
70[register_array.config]
72array_length = 3
73description = "A register array"
75# ------------------------------------------------------------------------------
76[register_array.config.register.input_settings]
78description = "Input configuration"
79mode = "r_w"
81[register_array.config.register.input_settings.bit.enable]
83description = "Enable things"
84default_value = "1"
86[register_array.config.register.input_settings.integer.number]
88description = "Configure number"
89max_value = 3
90default_value = 1
92[register_array.config.register.input_settings.bit.disable]
94description = ""
95default_value = "0"
97[register_array.config.register.input_settings.enumeration.size]
99element.small = ""
100element.large = ""
103# ------------------------------------------------------------------------------
104[register_array.config.register.output_settings]
106mode = "w"
108[register_array.config.register.output_settings.bit_vector.data]
110width=16
111description = "Some data"
112default_value="0000000000000011"
115################################################################################
116[constant.burst_length_beats]
118value = 256
121################################################################################
122[constant.data_mask]
124value = "0b1100_1111"
125data_type = "unsigned"
126""",
127 )
129 with pytest.raises(ValueError) as exception_info:
130 from_toml(name="", toml_file=toml_path)
131 assert str(exception_info.value) == ("Found register data in old format. See message above.")
133 new_toml_path = tmp_path / "regs_version_6_format.toml"
135 # Parsing of fixed file should pass without error.
136 from_toml(name="", toml_file=new_toml_path)
138 got = _load_toml_file(file_path=new_toml_path)
140 # Expected data in the new format.
141 # Note that the bit fields have been grouped together, and not in the order they appeared
142 # in the original TOML.
143 expected = {
144 "data": {"mode": "w"},
145 "status": {
146 "mode": "r_w",
147 "description": "Status register",
148 "bad": {"type": "bit", "description": "Bad things happen"},
149 "not_good": {"type": "bit", "description": "", "default_value": "1"},
150 "direction": {
151 "type": "enumeration",
152 "description": "The direction mode",
153 "default_value": "input",
154 "element": {"passthrough": "", "input": "", "output": "use in output mode"},
155 },
156 "interrupts": {
157 "type": "bit_vector",
158 "width": 4,
159 "description": "Many interrupts",
160 "default_value": "0110",
161 },
162 "count": {
163 "type": "integer",
164 "description": "The number of things",
165 "min_value": -5,
166 "max_value": 15,
167 },
168 },
169 "config": {
170 "type": "register_array",
171 "array_length": 3,
172 "description": "A register array",
173 "input_settings": {
174 "description": "Input configuration",
175 "mode": "r_w",
176 "enable": {"type": "bit", "description": "Enable things", "default_value": "1"},
177 "disable": {"type": "bit", "description": "", "default_value": "0"},
178 "number": {
179 "type": "integer",
180 "description": "Configure number",
181 "max_value": 3,
182 "default_value": 1,
183 },
184 "size": {"type": "enumeration", "element": {"small": "", "large": ""}},
185 },
186 "output_settings": {
187 "mode": "w",
188 "data": {
189 "type": "bit_vector",
190 "width": 16,
191 "description": "Some data",
192 "default_value": "0000000000000011",
193 },
194 },
195 },
196 "burst_length_beats": {"type": "constant", "value": 256},
197 "data_mask": {"type": "constant", "value": "0b1100_1111", "data_type": "unsigned"},
198 }
200 assert got == expected
203def test_convert_small_json_file(tmp_path):
204 json_path = create_file(
205 file=tmp_path / "regs.json",
206 contents="""
207{
208 "register": {
209 "apa": {
210 "mode": "r_w",
211 "description": "Apa.",
212 "bit": {
213 "enable": {
214 "description": "Enable.",
215 "default_value": "1"
216 }
217 }
218 },
219 "hest": {
220 "mode": "r",
221 "description": "Hest.",
222 "bit": {
223 "disable": {
224 "description": "Disable."
225 }
226 }
227 }
228 }
229}
230""",
231 )
233 with pytest.raises(ValueError) as exception_info:
234 from_json(name="", json_file=json_path)
235 assert str(exception_info.value) == ("Found register data in old format. See message above.")
237 new_json_path = tmp_path / "regs_version_6_format.json"
239 # Parsing of fixed file should pass without error.
240 from_json(name="", json_file=new_json_path)
242 got = _load_json_file(file_path=new_json_path)
243 expected = {
244 "apa": {
245 "mode": "r_w",
246 "description": "Apa.",
247 "enable": {"type": "bit", "description": "Enable.", "default_value": "1"},
248 },
249 "hest": {
250 "mode": "r",
251 "description": "Hest.",
252 "disable": {"type": "bit", "description": "Disable."},
253 },
254 }
256 assert got == expected
259def test_convert_small_yaml_file(tmp_path):
260 yaml_path = create_file(
261 file=tmp_path / "regs.yaml",
262 contents="""
263register:
264 apa:
265 mode: r_w
266 description: Apa.
267 bit:
268 enable:
269 default_value: '1'
270 description: Enable.
272 hest:
273 mode: r
274 description: Hest.
275 bit:
276 disable:
277 description: Disable.
278""",
279 )
281 with pytest.raises(ValueError) as exception_info:
282 from_yaml(name="", yaml_file=yaml_path)
283 assert str(exception_info.value) == ("Found register data in old format. See message above.")
285 new_yaml_path = tmp_path / "regs_version_6_format.yaml"
287 # Parsing of fixed file should pass without error.
288 from_yaml(name="", yaml_file=new_yaml_path)
290 got = _load_yaml_file(file_path=new_yaml_path)
291 expected = {
292 "apa": {
293 "mode": "r_w",
294 "description": "Apa.",
295 "enable": {"type": "bit", "description": "Enable.", "default_value": "1"},
296 },
297 "hest": {
298 "mode": "r",
299 "description": "Hest.",
300 "disable": {"type": "bit", "description": "Disable."},
301 },
302 }
304 assert got == expected