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:
The first stage is to identify or generate a
!Configtag, which specifies the order that the!Groupsshould 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.Then the elaborator works through each entry in the config:
For each !Register tag, the referenced
!Groupis instantiated just once starting at the next available address.For each !Macro tag, the referenced
!Groupis instantiated as many times as the tag requests using the specified prefix. It is placed starting at the next available address that agrees with thealignconstraint.
For each placed
!Groupinstance aDFRegisterGroupis created, and the elaborator works through the register list converting each!Regto aDFRegisterand attaching it to the group. Each register will be placed at the next available address that agrees with itsalignparameter, unless an explicitaddris 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.
For each
!Regplaced as aDFRegisterwithin the group the elaborator works through the associated !Field list and createsDFRegisterFields. By default each field will be placed at the next available least-significant bit, but anlsbparameter 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