XML 2 Dict

XML2Dict is a Python utility which converts a final output XML to nested Python dictionaries, representing nodes, registers and bitfields.

You can provide custom Python functions to run at a node, register or bitfield level.

This can enable functions such as the ability to generate docs from a jinja template.

Usage

Ensure you import Xml2Dict into your python project:

from xml2vhdl.xml2dict import Xml2Dict

Initialise the Xml2Dict class. Here you have the following options:

Attribute

Description

custom_node_function

function that runs at every node. Must only contain one input which is the node_dict

custom_register_function

function that runs at every register. Must only contain one input which is the register_dict

custom_bitfield_function

function that runs at every bitfield. Must only contain one input which is the bitfield_dict

escape_function

function that runs converts a string and escapes it for a particular language

merge_registers

bool to say if registers are going to be merged in the parsed output

acronyms

list of string words which are capitalized in the _hr formats

substitutions

list of tuple of key and values to substitute in the _hr formats

An example can be seen here:

xml_to_dict = Xml2Dict(custom_node_function=custom_node_function,
                       custom_register_function=custom_register_function,
                       custom_bitfield_function=custom_bitfield_function,
                       escape_function=escape_rst,
                       merge_registers=True)

Then you can parse xml using the parse_xml_to_dict method with the following options:

Attribute

Description

xml_file_path

path to final output xml, this is required

collapse_level

maximum number of levels of nested nodes

An example can be seen here:

xml_to_dict.parse_xml_to_dict(xml_file_path, collapse_level=3)

Dictionary Keys

Here are a list of all attributes that a Node, register and Bitfield dict can have:

Nodes

Attribute

Type

Description

id

str

node id string, directly from XML, see Generated Output for details

type

str

is always “node” for a node dictionary

path

List[str]

List of id to current node, excluding the current id

node

ElementTree.Element

the current ElementTree.Element, that the node dict is based on

hw_type

str

see Generated Output for details

byte_size

int

see Generated Output for details

link_done

str

see Generated Output for details

absolute_offset

str

see Generated Output for details

address

str

Capitalized Hex format of relative address e.g. 0x008A0000

absolute_address

str

Capitalized Hex format of absolute address e.g. 0x008A0000

absolute_id

str

see Generated Output for details

path_hr

List[str]

Human readable format of path

absolute_id_hr

str

Human readable format of absolute_id

id_hr

str

Human readable format of id

id_upper

str

Upper format of id

id_lower

str

Lower format of id

children_nodes

List[dict]

list of node dictionaries of child nodes

children_registers

List[dict]

list of registers dictionaries of child registers

children_missing_description

Bool

Any child register or nodes are missing a description

children_missing_bitfield_description

Bool

Any child bitfields are missing a description, no matter the level

has_bitfields

Bool

Any of the child registers has bitfields

Registers

Attribute

Type

Description

id

str

register id string, directly from XML, see Generated Output for details. If there are multiple merged registers, only gives the first id.

path

List[str]

List of id to current register, excluding the current id

register

ElementTree.Element

the current ElementTree.Element, that the register dict is based on

type

str

is always “register” for a register dictionary

name

str

id of merged together registers, e.g. register_<0..15>

absolute_id

str

see Generated Output for details

absolute_offset

str

see Generated Output for details

address

str

Capitalized Hex format of relative address e.g. 0x008A0000

absolute_address

str

Capitalized Hex format of absolute address e.g. 0x008A0000

description

str

see Generated Output for details

missing_description

Bool

Current register is missing a description

size

int

see Generated Output for details

type_name

str

Can be “register” or “look up table”

adjusted_size

int

Number of Registers including both merged registers and entries in look up table

software_permissions

str

Capitalized permissions. Replaces R with RO.

reset_value

str

reset_value of register, directly from output xml

bitfields

List[dict]

List of bitfield dictionaries

bitfield_names

List[str]

List of bitfield names

width

int

Width in bits of mask

from_bit

int

First bit index, where the mask is high

to_bit

int

Last bit index, where the mask is high

mask

str

Capitalized Hex format (0x<mask>) of the register mask

missing_bitfield_description

bool

Any of the registers bitfields is missing a description

field_list

List[dict]

see field_list dict for details

last_merged_register

dict

dictionary of last merged register

nof_merged_register

int

Number of merged registers in current dictionary

id_upper

str

upper format of id

id_lower

str

lower format of id

name_upper

str

upper format of name

name_lower

str

lower format of name

path_hr

List[str]

Human readable format of path

absolute_id_hr

str

Human readable format of absolute_id

id_hr

str

Human readable format of id

name_hr

str

Human readable format of name

field_list dict

A list of dictionaries containing all fields including unused ones. Unused fields have blank names. List starts from least significant bits to most.

Note

This assumes all registers are 32 bits.

Dictionary Attribute

Type

Description

name

str

“” if unused, bitfield[“id”] if bitfield, register[“name”] if register field

name_upper

str

“” if unused, bitfield[“id_upper”] if bitfield, register[“name_upper”] if register field

name_lower

str

“” if unused, bitfield[“id_lower”] if bitfield, register[“name_lower”] if register field

width

str

width of field in bits

from_bit

int

integer value representing the from bit index of the field

to_bit

int

integer value representing the to bit index of the field

Bitfields

Attribute

Type

Description

id

str

bitfield id string, directly from XML, see Generated Output for details

path

List[str]

List of id to current bitfield, excluding the current id

id_upper

str

Upper format of id

id_lower

str

lower format of id

bitfield

ElementTree.Element

the current ElementTree.Element, that the bitfield dict is based on

description

str

description from xml, parsed through an custom escape function. If "" or "Missing description", it is replaced by "<Description missing from XML>"

missing_description

bool

Current bitfield is missing a description

type

str

is always “bitfield” for a bitfield dictionary

absolute_id

str

see Generated Output for details

absolute_offset

str

see Generated Output for details

reset_value

str

reset_value of bitfield, directly from output xml

mask

str

Capitalized Hex format (0x<mask>) of the register mask

from_bit

int

First bit index, where the mask is high

to_bit

int

Last bit index, where the mask is high

width

int

Width in bits of mask

software_permissions

str

Capitalized permissions. Replaces R with RO.

path_hr

List[str]

Human readable format of path

absolute_id_hr

str

Human readable format of absolute_id

id_hr

str

Human readable format of id

Formats

Human Readable Format

_hr is a Human readable format, which breaks up a string into words by splitting by . and _. If the word matches any given acronyms, or acronym with an s, the acronym is capitalized. If the word/words match any word/words in the substitutions list, the substitution is made. The First letter of each word is capitalized. Any . are replaced with -.

Upper Format

_upper is a Upper format, with everything capitalized and "_" replaced with " ".

Lower Format

_upper is a Upper format, with everything lower case and "_" replaced with " ".

Merging Registers

If merge_registers is set to true, one register dictionary can hold the information for multiple registers.

Registers can be merged if:

  • in format name_<int>

  • are next to each other

  • have same bitfields

  • have consecutive integers

The id and description remain the id and description of the first register. A name is changed from id to name_<int_from_first_reg..int_from_last_reg>.

Collapsing Nodes

The max number of nested dictionary levels can be set by the collapse_level. When collapsing nodes, all id (both register and nodes) are replaced with . joining all ids of collapsed nodes and registers.

You can get a flat node by setting the collapse_level to 0.