Scoping - Minres/CoreDSL GitHub Wiki
CoreDSL 2 defines the following three types of scopes:
- ISA scope: Contains parameters, registers and address spaces declared in the
architectural_statesection as well as functions declared in thefunctionssection.- The ISA scope of an
InstructionSetis nested in the ISA scope of theInstructionSetreferenced by theextendsclause. - The ISA scope of a
Coremay have multiple parent scopes, corresponding to the ISA scopes of theInstructionSetslisted in theprovidesclause.
- The ISA scope of an
- instruction/function scope: Contains the named bitfields in the encoding specification (instructions) respectively the formal arguments (functions), and is nested in the ISA scope.
- block scopes: Contain local variable declarations. Block scopes are nested according to the usual C rules and the control structure of the
behaviorspecification. The outermost block scope is nested in the surrounding instruction/function scope.
The following rules apply to all scope types:
- Every identifier can be declared at most once per scope.
- An identifier reference binds to the first declaration that is encountered when traversing the scope hierarchy outwards.
- Given an ISA scope with multiple parents (e.g. corresponding to
Core Y provides A, B, C), the parent scopes shall be traversed in the same order as given in theprovidesclause (e.g. try to resolve an identifier first inA, if unsuccessful, try inB, and lastly try inC.
- Given an ISA scope with multiple parents (e.g. corresponding to
- Local declarations may shadow more global ones.
- Inside a particular scope, only declarations occurring before (according to the source code order) are visible.
Example
InstructionSet A {
// ISA scope: param_A, foo_A
architectural_state {
signed<32> param_A;
}
instructions {
INST_A {
encoding: field_A[15:0] :: 0xABCD;
behavior:
// instruction scope: field_A + ISA scope
{
// block scope: local_A, local_A2 + instruction scope
signed<32> local_A;
// visible here: local_A + instruction scope
if (field_A < 42) {
// nested block scope 1: local_AA + block scope
signed<32> local_AA;
} else {
// nested block scope 2: local_A + block scope
signed<32> local_A; // shadows local_A from block scope
}
signed<32> local_A2;
// visible here: local_A, local_A2 + instruction scope
}
}
}
functions {
void foo_A(signed<32> arg_A) {
// function scope: arg_A + ISA scope
// see instruction above for block scopes
}
}
}
InstructionSet B extends A {
// ISA scope: param_B, foo_A, param_A
architectural_state {
signed<32> param_B;
}
}
InstructionSet C {
// ISA scope: param_C
architectural_state {
signed<32> param_C;
}
}
Core Z provides B, C {
// ISA scope: param_Z, param_B, foo_A, param_A, param_C
architectural_state {
signed<32> param_Z;
}
}