Working with data files
The register parser reads a data file and constructs a RegisterList
object.
It is important that the data file is formatted correctly and has the necessary properties.
The register parser will warn if there are any errors in the data, such as missing properties,
unknown properties, wrong data type for properties, etc.
The register parser is implemented in the RegisterParser
class.
It can be called with the from_toml()
and from_json()
functions.
Why TOML?
The TOML data file format is highly recommended for specifying your registers.
It is a configuration file format that is easy to both read and write. Compared to XML, YAML and JSON, which would be the most obvious alternatives, it has the following advantages that are relevant when handling FPGA registers:
Supports comments in file.
Supports hexadecimal and binary integer values, with optional underscore separator.
Clear and readable handling of multiline strings.
Duplicate ley is an error.
Fewer control characters compared to XML and JSON.
Very fast Python parser available.
Furthermore, while readability can be considered subjective, the TOML format is considered quite obvious and easy to read.
TOML Format
Below is an example of a typical TOML file, which can be parsed with a call to from_toml()
.
It sets up:
Two registers with different modes.
One of which contains a bit field and an enumeration field.
A register array with two registers and fields.
An integer constant and a float constant.
See the menu sidebar for details about how to set up the different fields, constants, etc.
Also, see the “generator” articles for insight into the code that can be generated from this definition file. For example, the human-readable documentation from the data below can be seen in the HTML code generator article.
1################################################################################
2[register.config]
3
4# The "mode" property MUST be present for a register.
5# The value specified must be a valid shorthand mode name. Either of:
6# * "r" for Read.
7# * "w" for Write.
8# * "r_w" for Read, Write.
9# * "wpulse" for Write-pulse.
10# * "r_wpulse" for Read, Write-pulse.
11# See https://hdl-registers.com/rst/basic_feature/basic_feature_register_modes.html for details.
12mode = "r_w"
13# The "description" property is optional for a register.
14# Will default to "" if not specified.
15# The value specified must be a string.
16description = """
17This is the description of my register.
18
19Rudimentary RST formatting can be used, such as **boldface** and *italics*.
20"""
21
22[register.config.bit.enable]
23
24description = "Enable operation."
25default_value = "1"
26
27[register.config.enumeration.direction]
28
29description = "Set the data direction."
30default_value = "high_z"
31
32element.data_in = "Receive data from outside the FPGA."
33element.high_z = """
34Set pins to high impedance.
35
36Will not process any incoming data, nor send anything out.
37"""
38element.data_out = "Send data from FPGA."
39
40
41################################################################################
42[register.status]
43
44mode = "r"
45
46
47################################################################################
48[register_array.channels]
49
50array_length = 4
51description = "Configuration for each channel."
52
53
54# ------------------------------------------------------------------------------
55[register_array.channels.register.read_address]
56
57mode = "r_w"
58description = "Read address for DMA data."
59
60
61# ------------------------------------------------------------------------------
62[register_array.channels.register.config]
63
64mode = "w"
65description = "Configuration of channel settings."
66
67bit.enable.description = "Enable this channel."
68
69bit_vector.tuser.width = 8
70bit_vector.tuser.description = "**TUSER** value for this channel."
71
72
73################################################################################
74[constant.axi_data_width]
75
76value = 64
77description = "Data width of the AXI port used by this module."
78
79
80################################################################################
81[constant.clock_rate_hz]
82
83value = 156.25e6
84description = "The clock rate used in the system, given in Hertz."
Using JSON data file
The TOML format is highly recommended due to the benefits it offers, listed above. Also all the examples on this website are using TOML. However, the tool also supports using JSON data files if that is desired.
In this case you need to construct your JSON data on the exact format as the
TOML format above and then parse it with a call to from_json()
.
Below is an example JSON snippet that sets up some register data:
1{
2 "register": {
3 "configuration": {
4 "mode": "r_w",
5 "description": "Configuration register.",
6 "bit": {
7 "enable": {
8 "description": "Enable data passthrough.",
9 "default_value": "1"
10 }
11 }
12 },
13 "status": {
14 "mode": "r",
15 "description": "General status register."
16 }
17 },
18 "constant": {
19 "data_width": {
20 "value": 64,
21 "description": "The width of the AXI port used by the module."
22 },
23 "clk_frequency_hz": {
24 "value": 156250000.0,
25 "description": "The system clock frequency in Hertz."
26 }
27 }
28}
Other data file formats
The TOML format is highly recommended due to the benefits it offers, listed above. However, if using another data file format is necessary then that is also possible. See this article for details: Using other data file formats.