-
Notifications
You must be signed in to change notification settings - Fork 3
Scoping
Julian Oppermann edited this page May 23, 2022
·
15 revisions
CoreDSL 2 defines the following three types of scopes:
-
ISA scope: Contains parameters, registers and address spaces declared in the
architectural_state
section as well as functions declared in thefunctions
section.- The ISA scope of an
InstructionSet
is nested in the ISA scope of theInstructionSet
referenced by theextends
clause. - The ISA scope of a
Core
may have multiple parent scopes, corresponding to the ISA scopes of theInstructionSets
listed in theprovides
clause.
- 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
behavior
specification. 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 theprovides
clause (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;
}
}