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.
.. code-block:: yaml
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.
.. code-block:: python
import register_map
myMap = registerMap.load( 'registermap.yml' )
Let's test that the register map properties are loaded as expected.
.. code-block:: python
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.
.. code-block:: python
import register_map
myMap = registerMap.RegisterMap()
myMap.addModule( 'mymodule' )
myRegister = myMap['modules'][ 'mymodule' ].addRegister( 'myregister' )
myField = myRegister.addField( 'my-field', [2, 4] )
registerMap.save('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
^^^^^^^^^^^^^^^^^
.. code-block:: yaml
modules:
- module:
constraints: {}
description: ''
instances: 1
name: mymodule
registers: []
summary: ''
The ``instances`` properties is used when you are creating a series module.
Creating a register
^^^^^^^^^^^^^^^^^^^
.. code-block:: yaml
registers:
- register:
bitFields:[]
bitmap:
- destination: '[0:2]'
destinationId: mymodule.myregister.my-field,
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
^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: yaml
bitFields:
- 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.
Notes:
* The register ``m1.myregister`` has a local field ``my-field``. The destination bit mapping uses
a "third level" canonical id to address the field; ``m1.myregister.my-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).
.. code-block:: yaml
registerMap:
modules:
- module:
name: m1
registers:
- register:
bitFields:
- field: {description: '', name: my-field, parent: mymodule.myregister,
resetValue: 0x0, size: 3, summary: ''}
- field: {description: '', name: my-global-field, resetValue: 0x0, size: 6,
summary: ''}
bitmap:
- {destination: '[0:2]', destinationId: m1.myregister.my-field, source: '[2:4]'}
- {destination: '[3:5]', destinationId: my-global-field, source: '[5:7]'}
name: myregister
- module:
name: m2
registers:
- register:
bitFields: []
bitmap:
- {destination: '[0:2]', destinationId: my-global-field, source: '[1:3]'}
name: other_register