C code generator

A C header can be generated, that contains all information about registers, fields and constants. The code is generated from the CHeaderGenerator class by calling the RegisterCodeGenerator.create() method.

Python code that parses the example TOML file and generates the C code we need.
 1# Standard libraries
 2import sys
 3from pathlib import Path
 4
 5# First party libraries
 6from hdl_registers.generator.c.header import CHeaderGenerator
 7from hdl_registers.parser.toml import from_toml
 8
 9THIS_DIR = Path(__file__).parent
10
11
12def main(output_folder: Path):
13    """
14    Create register C artifacts from the TOML example file.
15    """
16    register_list = from_toml(
17        name="example",
18        toml_file=THIS_DIR.parent.parent / "user_guide" / "toml" / "toml_format.toml",
19    )
20
21    CHeaderGenerator(register_list=register_list, output_folder=output_folder).create()
22
23
24if __name__ == "__main__":
25    main(output_folder=Path(sys.argv[1]))

The C header provides two methods for usage: A struct that can be memory mapped, or address definitions that can be offset a base address. For the addresses, array registers use a macro with an array index argument.

Below is the resulting code from the TOML format example:

example_regs.h
 1// This file is automatically generated by hdl-registers version 5.2.1-dev.
 2// Code generator CHeaderGenerator version 1.0.0.
 3// Generated 2024-05-21 20:51 from file toml_format.toml at commit 2f4170d05b13abac.
 4// Register hash 0d636d16ec9bdadff4d5e144aaacd9416830c91d.
 5
 6#ifndef EXAMPLE_REGS_H
 7#define EXAMPLE_REGS_H
 8
 9// Value of register constant 'axi_data_width'.
10#define EXAMPLE_AXI_DATA_WIDTH (64)
11// Value of register constant 'clock_rate_hz'.
12#define EXAMPLE_CLOCK_RATE_HZ (156250000.0)
13
14// Number of registers within this register map.
15#define EXAMPLE_NUM_REGS (10u)
16
17// Type for the 'channels' register array.
18typedef struct example_channels_t
19{
20  // Mode 'Read, Write'.
21  uint32_t read_address;
22  // Mode 'Write'.
23  uint32_t config;
24} example_channels_t;
25
26// Type for this register map.
27typedef struct example_regs_t
28{
29  // Mode "Read, Write".
30  uint32_t config;
31  // Mode "Read".
32  uint32_t status;
33  example_channels_t channels[4];
34} example_regs_t;
35
36// Address of the 'config' register.
37// Mode 'Read, Write'.
38#define EXAMPLE_CONFIG_INDEX (0u)
39#define EXAMPLE_CONFIG_ADDR (4u * EXAMPLE_CONFIG_INDEX)
40// Attributes for the 'enable' field in the 'config' register.
41#define EXAMPLE_CONFIG_ENABLE_SHIFT (0u)
42#define EXAMPLE_CONFIG_ENABLE_MASK (0b1u << 0u)
43#define EXAMPLE_CONFIG_ENABLE_MASK_INVERSE (~EXAMPLE_CONFIG_ENABLE_MASK)
44// Attributes for the 'direction' field in the 'config' register.
45#define EXAMPLE_CONFIG_DIRECTION_SHIFT (1u)
46#define EXAMPLE_CONFIG_DIRECTION_MASK (0b11u << 1u)
47#define EXAMPLE_CONFIG_DIRECTION_MASK_INVERSE (~EXAMPLE_CONFIG_DIRECTION_MASK)
48enum ExampleConfigDirection
49{
50  EXAMPLE_CONFIG_DIRECTION_DATA_IN = 0,
51  EXAMPLE_CONFIG_DIRECTION_HIGH_Z = 1,
52  EXAMPLE_CONFIG_DIRECTION_DATA_OUT = 2,
53};
54
55// Address of the 'status' register.
56// Mode 'Read'.
57#define EXAMPLE_STATUS_INDEX (1u)
58#define EXAMPLE_STATUS_ADDR (4u * EXAMPLE_STATUS_INDEX)
59
60// Address of the 'read_address' register within the 'channels' register array (array_index < 4).
61// Mode 'Read, Write'.
62#define EXAMPLE_CHANNELS_READ_ADDRESS_INDEX(array_index) (2u + (array_index) * 2u + 0u)
63#define EXAMPLE_CHANNELS_READ_ADDRESS_ADDR(array_index) (4u * EXAMPLE_CHANNELS_READ_ADDRESS_INDEX(array_index))
64
65// Address of the 'config' register within the 'channels' register array (array_index < 4).
66// Mode 'Write'.
67#define EXAMPLE_CHANNELS_CONFIG_INDEX(array_index) (2u + (array_index) * 2u + 1u)
68#define EXAMPLE_CHANNELS_CONFIG_ADDR(array_index) (4u * EXAMPLE_CHANNELS_CONFIG_INDEX(array_index))
69// Attributes for the 'enable' field in the 'config' register within the 'channels' register array.
70#define EXAMPLE_CHANNELS_CONFIG_ENABLE_SHIFT (0u)
71#define EXAMPLE_CHANNELS_CONFIG_ENABLE_MASK (0b1u << 0u)
72#define EXAMPLE_CHANNELS_CONFIG_ENABLE_MASK_INVERSE (~EXAMPLE_CHANNELS_CONFIG_ENABLE_MASK)
73// Attributes for the 'tuser' field in the 'config' register within the 'channels' register array.
74#define EXAMPLE_CHANNELS_CONFIG_TUSER_SHIFT (1u)
75#define EXAMPLE_CHANNELS_CONFIG_TUSER_MASK (0b11111111u << 1u)
76#define EXAMPLE_CHANNELS_CONFIG_TUSER_MASK_INVERSE (~EXAMPLE_CHANNELS_CONFIG_TUSER_MASK)
77
78#endif // EXAMPLE_REGS_H