XML Parser API

Data types for working with SoC register maps.

The HTI Reg XML concept is that a given peripheral on an SoC bus can be described using XML. That XML file can then be used to cogenerate C header files, VHDL, documentation, etc.

There are two different types of XML files, those describing components, and those describing memory maps.

A memory map file has a MemoryMap element as its root object. This memory map is then filled with Instances or Arrays of Instances. Instances have an extern attribute, in which a Component is named.

A component file has a Component as its root object. This component is filled with Registers (or Arrays of Registers), which correspond to memory locations in the component. Each Register can be made up of multiple Fields (or Arrays of Fields) representing bitfields in the register. Each Field can be made up of Enums, which provide named enumeration constants for non-numeric fields.

The name of the Component is then named in the extern attribute of an Instance, which binds one or more copies of the Component onto the MemoryMap.

Most of these elements have elements called “offset” and “size”. These are what determine how large the element is, and where it is located. For instance, in a Field, these refer to bit positions: a Field with a size of 4 and an offset of 4 is a field that is one nibble large, located at the second least significant nibble of the word. For a Register, these discuss word addresses. And for an Instance, these discuss bytes in memory.

Once the XML files are written, the XmlReader class is used to turn each file into a memory representation, with all of the above classes derived from the HtiElement class.

The reading process will also create sourcefile and sourceline members for all contained classes. This is useful both for generating outputs and for debugging.

Rob Gaddi, Highland Technology. May 31, 2011

HtiElement Base Class

class registermaps.xml_parser.HtiElement(xml_element, parent=None, sourcefile='unknown file')

Abstract base class for all elements.

In addition to the attributes below provided for all classes, all attributes provided by the XML (or through the default mechanisms) are available through the standard Python attribute syntax.

required and optional are both dicts that map attribute names to typefn functions, i.e. functions that turn a single str input into values of the correct type. str() is an example of this, as are int() and bool(), though the locally provided functions toint() and tf() are more suitable for getting these values in this context.

parent

The parent object for this element.

Type:HtiElement
space

A space filled with the children of this object

Type:Space
description

A list of description text, one paragraph per element.

Type:list of str
required

Set in subclasses to map required attribute names to typefns. All subclasses require ‘name’ by default. To avoid this, put 'name' : None in required.

Type:dict
optional

Set in subclases to map optional attribute names to typefns.

Type:dict
defaults

Default values for attributes. Attributes must be present in either required or optional. Value can also be a function of one argument, which is self, in which case the function is called and the attribute given the value returned.

inherit(), is a factory for default functions that retrieve a given attribute value from the element’s parent.

When using defaults, they will not be passed through the typefn from optional.

Type:dict
space_size

Initialization argument for space

Type:int
space_placer

Initialization argument for space

Type:class
space_resizer

Initialization argument for space

Type:class
textasdesc

If True (default), bare text inside of the element will become a child <description> element.

Type:bool
afterchildren()

Hook to modify the object after the Space is created and filled.

If size is (still) None at the end of this, will be auto-set to space.size If readOnly is (still) None at the end of this, it will try to learn from its children.

attributes()

Return a dict of attributes.

beforechildren()

Hook to modify the object before the Space is created and filled.

description

Iterable of description lines.

Yields:One line at a time of description. There is no length limit, but no line will contain a newline character.
place(po)

Hook to notify a object it has been placed in its parent.

po is a PlacedObject where obj is self.

space_placer

alias of registermaps.space.NoPlacer

space_resizer

alias of registermaps.space.NoResizer

class registermaps.xml_parser.Description(xml_element, parent, sourcefile='unknown file')

Defines a Description element, which is a child of practically any HtiElement.

Upon its creation, a Description will insert itself into the description list of its parent.

registermaps.xml_parser.inherit(fieldname)

Create a function that returns fieldname from the parent object.

Example

>>> defaults = {
...    'readOnly' : inherit('readOnly')
... }
registermaps.xml_parser.tf(text)

Convert common string representations of true and false to bool.

registermaps.xml_parser.toint(text)

str to int that accepts either decimal or “0x…” hex strings

HtiElement Component Subclasses

class registermaps.xml_parser.Component(xml_element, parent=None, sourcefile='unknown file')

Components represent entire logic blocks of several Registers. They can be tied to a MemoryMap by using Instances.

class registermaps.xml_parser.RegisterArray(xml_element, parent=None, sourcefile='unknown file')
class registermaps.xml_parser.Register(xml_element, parent=None, sourcefile='unknown file')

Registers are contained within components.

class registermaps.xml_parser.Field(xml_element, parent=None, sourcefile='unknown file')

Fields represent bit fields and contained within Registers.

They may hold enumeration values in a Space.

class registermaps.xml_parser.Enum(xml_element, parent=None, sourcefile='unknown file')

Enums can be used to better define fields.

HtiElement MemoryMap Subclasses

class registermaps.xml_parser.MemoryMap(xml_element, components, sourcefile='unknown file')

A MemoryMap contains several Instances.

When creating one, rather than a parent (which it will never have) it must be given a dict associating Components with their names.

class registermaps.xml_parser.Instance(xml_element, parent=None, sourcefile='unknown file')

Instances bind Components to a MemoryMap.

They must be created after the corresponding Components if no explicit size is given. Size is in bytes, whereas Component size was in words.

XML File Parsing

class registermaps.xml_parser.XmlParser

Used to parse one or more source files or directories into a collection of Components and MemoryMaps.

analyzeDirectory(path)

Parse all .xml file in a directory.

Appends to the componentxml and mmxml fields.

Any XML files not rooted in a component or memorymap will throw an error.

path supports the **/ syntax, meaning “this directory and all subdirectories.”

elaborate()

Translates XML into HtiElements.

.componentxml will be turned into .components (and cleared) .mmxml will be turned into .memorymaps (and cleared)

processDirectory(path)

Parses all .xml files in a directory and turns then into HtiElements.

This combines analyzeDirectory and elaborate into one call for the common case where all sources are in the same directory.

exception registermaps.xml_parser.XmlError(msg, element, sourcefile='unknown file')

Documents an error while parsing the XML.

msg

The error message.

Type:str
sourcefile

The filename where the error occured.

Type:str
element

The XML element where the error occured.

Type:lxml.etree._Element