Register Elaboration

The register set for a block is described in the YAML schema by !Config, !Group, and !Reg tags. These are elaborated into DFRegisterGroups and DFRegisters by BLADE, resolving all addresses and flattenning out any repetitions (where array is greater than 1).

The elaboration works over a few stages to build the final register set:

  1. The first stage is to identify or generate a !Config tag, which specifies the order that the !Groups should be instantiated. If one can be found in the document scope then it is used, otherwise one is automatically created - placing all non-macro groups in the same order that they are declared in the file.

  2. Then the elaborator works through each entry in the config:

    • For each !Register tag, the referenced !Group is instantiated just once starting at the next available address.

    • For each !Macro tag, the referenced !Group is instantiated as many times as the tag requests using the specified prefix. It is placed starting at the next available address that agrees with the align constraint.

  3. For each placed !Group instance a DFRegisterGroup is created, and the elaborator works through the register list converting each !Reg to a DFRegister and attaching it to the group. Each register will be placed at the next available address that agrees with its align parameter, unless an explicit addr is specified in which case the address will be forced. Overlaps between registers are detected and an exception will be thrown to abort the elaboration, details of the conflict will be included in the error message.

    • If a register has one of the expansion options (see below), then it will be expanded as the first stage of handling the group. This allows the rest of the elaboration process to continue as if the registers had been present in the original description.

  4. For each !Reg placed as a DFRegister within the group the elaborator works through the associated !Field list and creates DFRegisterFields. By default each field will be placed at the next available least-significant bit, but an lsb parameter can be provided to force a certain position. Overlaps between fields are detected and an exception will be thrown to abort the elaboration, details of the fields that conflict will be included in the error message.

Further details on the exact placement of registers and fields can be found in the source code for the register elaborator.

Expansions

If certain keys are present within the options array for a !Reg then the elaborator will change its behaviour. These are:

Option Effect
event Requires interrupt handling registers such as MSTA and RSTA
setclear Requires set-clear registers such as SET, CLEAR, and STATUS

Further details on what these expansions do can be found in the schema documentation for the !Reg tag. The API for the expansion functions can be seen below.

API

blade.elaborate.registers.build_group(group, is_macro, next_addr, scope, defs_scope, m_prefix=None, m_array=None, m_align=None)

Expand a !Group into a set of DFRegisters, taking account of the ‘array’ value to expand multiple instances. Returns a list of DFRegisterGroups - one per group instance.

Parameters
  • group – The group to expand

  • is_macro – Whether this group has been declared as a macro

  • next_addr – The next free byte-address to allocate

  • scope – The ElaboratorScope object for resolving references

  • defs_scope – Hierarchical scope of !Define values related to this group

  • m_prefix – Prefix for registers when evaluating a macro (default: None)

  • m_array – Number of instances when evaluating a macro (default: None)

  • m_align – Alignment of each instance when evaluating a macro (default: None)

Returns

Tuple of the constructed DFRegisterGroup and the next free address

Return type

tuple

blade.elaborate.registers.build_register(group, reg, address, iteration, scope, defs_scope, m_prefix=None)

Evaluate a !Reg into an instance of DFRegister, handling different naming conventions depending whether or not it is being generated under a !Macro.

Parameters
  • group – The !Group tag containing this register.

  • reg – The !Reg tag to evaluate

  • address – The address the register has been placed at

  • iteration – The current iteration we’re on (!Reg.array can be > 1)

  • scope – The ElaboratorScope object

  • defs_scope – Hierarchical scope of !Define values related to this group

  • m_prefix – Prefix for registers created by a macro (default: None)

Returns

The constructed register

Return type

DFRegister

blade.elaborate.registers.elaborate_registers(top, scope, max_depth=None)

Evaluate either a !Config expanding into a list of registers. !Registers or !Macros considered in the order specified in the !Config.

Parameters
  • top – The top-level !Config tags to evaluate

  • scope – An ElaboratorScope object containing all documents included directly or indirectly by the top module.

  • max_depth – Ignored for now

Returns

List of all constructed DFRegisterGroups

Return type

list

blade.elaborate.registers.resolve_xref(xref=[], ref=None, scope=None, ctx={})

Resolve a value cross-reference of the form ‘<group>/<reg>/<field>/<param>’. Note that the modified context allows ‘self’ to be resolved in nested references

Parameters
  • xref – Tuple of items identifying a cross-referenced parameter

  • ref – Identifier of a referenced parameter on this instance (not used)

  • scope – The ElaboratorScope object for wider-crossreferencing

  • ctx – Context to use for resolving the cross-reference

Returns

Tuple of the value of the crossreference and a modified context

Return type

tuple

API: Event Expansion

blade.elaborate.register_interrupt.expand(regs)

Perform expansion of !Reg tags into interrupt register sets if they have the correct options present.

Parameters

regs – The !Reg tags to expand

Returns

Complete list of registers after the expansion (some registers may

have been removed)

Return type

list

blade.elaborate.register_interrupt.modify_fields(fields, prefix, reset=None, width=None)

Generate a new set of fields with a specified prefix, reset, and width

Parameters
  • fields – Lists of fields to duplicate

  • prefix – The prefix for each field’s description

  • reset – The reset value for the field (can be a function, default: None)

  • width – The width of the field (can be a function, default: None)

Returns

Set of modified fields

Return type

list

blade.elaborate.register_interrupt.perform_event_expansion(reg, has_mode, has_level)

For !Reg containing the ‘event’ option, expand the defined registers.

Parameters
  • reg – The register to expand

  • has_mode – Whether or not the level/edge mode register should be created

  • has_level – Whether or not the level sensitivity register should be created

Returns

Set of DFRegisters that have expanded from the input

Return type

list

API: Set-Clear Expansion

blade.elaborate.register_setclear.expand(regs)

Perform expansion of !Reg tags into set-clear register sets if they have the correct options present.

Parameters

regs – The !Reg tags to expand

Returns

Complete list of registers after the expansion (some registers may

have been removed)

Return type

list

blade.elaborate.register_setclear.modify_fields(fields, desc)

Generate a new set of fields with a specified suffix.

Parameters
  • fields – Lists of fields to duplicate

  • desc – Each field’s description

Returns

Set of modified fields

Return type

list

blade.elaborate.register_setclear.perform_setclear_expansion(reg)

For !Reg containing the ‘setclear’ option, expand the defined registers.

Parameters

reg – The register to expand

Returns

Set of DFRegisters that have been expanded from the input

Return type

list