Getting started using a YAML file

Using a text editor you can define the YAML structure of your register map relatively easily. It gets a little easier if you use an editor that understands YAML, such as Notepad++ or an IDE such as PyCharm.

The example below shows a register map skeleton that defines some properties of the memory space, along with a summary and description of the register map. The modules section is left blank for now.

In any register map you must have at least one module.

registerMap: {
  # A memorySpace is not optional
  memorySpace: {
    # but all the parameters are optional.
    # Default: 0x0
    baseAddress: 0x1000
    # Default: None
    pageSize: None
    # Default: 32
    addressBits: 48
    # Default: 8
    memoryUnitBits: 16
  summary: 'A short summary of the register map'
  description: 'A longer description of the register map'
  modules: [

When you are done and have saved your YAML data to a file, your YAML register map can be loaded into Python.

import register_map
myMap = registerMap.load( 'registermap.yml' )

Let’s test that the register map properties are loaded as expected.

assert myMap.memory.addressBits == 48
assert myMap.memory.memoryUnitBits == 16
assert myMap.memory.baseAddress == 0x1000

Another way to quickly get started is to use the Python API to create a register map, export it to YAML and then copy-paste the YAML structures you find to create your data.

import register_map

myMap = registerMap.RegisterMap()
myMap.addModule( 'mymodule' )
myRegister = myMap['modules'][ 'mymodule' ].addRegister( 'myregister' )
myField = myRegister.addField( 'my-field', [2, 4] )'myMap.yml', myMap)

When you initially create a map this way, or whenever you save register map YAML from Python you will notice a number of properties with an underscore (‘_’) prefix. These are included for reference for a human reader but the values themselves are automatically calculated; you should not modify them, but if you do, don’t expect your modifications to persist as changes will be overwritten the next time you same YAML from Python and they will never have any effect when loaded into Python.

Creating a module

  - module:
      constraints: {}
      description: ''
      instances: 1
      name: mymodule
      registers: []
      summary: ''

The instances properties is used when you are creating a series module.

Creating a register

- register:
    - destination: '[0:2]'
      source: '[2:4]'
    constraints: {}
    description: ''
    global: false
    mode: rw
    name: myregister
    public: true
    summary: ''

The particularly complicated bit here is defining the bitmap; when using Python this is taken care of to varying degrees by the Python API, depending on the complexity of your bit mapping. The bit map maps the bits of a member field to the bits of the register. The destination bit range is the bit indices of the field. The destinationId is the canonical ID of the field you are mapping and the source is the bit range of the register.

In the example above, bits [0:2] of the bit field are mapped to bits [2:4] of the register.

The definition of the bit field itself is described in the next section.

The global property is always false for now. It is a placeholder for a global register feature.

Creating a local field

- field:
    description: ''
    name: my-field
    parent: mymodule.myregister
    resetValue: 0x0
    size: 3
    summary: ''

The parent property is required to identify the bit field as local to the register and not global (see below).

Creating a global field

A global field means that you intend to take the bits of that field and distribute them across multiple registers and modules. As a general rule a global field is not recommended at all for various reasons, not the least of which is that it greatly complicates software required to read, write and manage such “distributed” fields. It is supported here because hardware designers sometimes find it necessary to jam field bits into obscure locations and so a register map description should be able to accommodate this.

In YAML, a global field must have one and only one instantiation that defines the reset value and size of the field. Subsequent declarations of the global field must only define which bits of the register are being attached to. A global field must not define a parent property.

In the example below we have two modules each with a register associating with a global field. To try and reduce the noise a bit, properties that don’t relate to the global field configuration have been dropped.


  • The register m1.myregister has a local field my-field. The destination bit mapping uses a “third level” canonical id to address the field;
  • The register m1.myregister contains the definition of the global field my-global-field in it’s bitFields section, including the reset value and size.
  • The register m2.other_register bitFields section is empty because it has no local fields and is associating with the global field that has already been defined in m1.myregister.
  • m2.other_register contain a bit mapping to the global field my-global-field
  • The global field my-global-field is always referenced using a “first level” canonical ID (just it’s name).
  - module:
      name: m1
      - register:
          - field: {description: '', name: my-field, parent: mymodule.myregister,
              resetValue: 0x0, size: 3, summary: ''}
          - field: {description: '', name: my-global-field, resetValue: 0x0, size: 6,
              summary: ''}
          - {destination: '[0:2]', destinationId:, source: '[2:4]'}
          - {destination: '[3:5]', destinationId: my-global-field, source: '[5:7]'}
          name: myregister
  - module:
      name: m2
      - register:
          bitFields: []
          - {destination: '[0:2]', destinationId: my-global-field, source: '[1:3]'}
          name: other_register