Skip to content

Scoping

Julian Oppermann edited this page May 21, 2021 · 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 the functions section.
    • The ISA scope of an InstructionSet is nested in the ISA scope of the InstructionSet referenced by the extends clause.
    • The ISA scope of a CoreDef may have multiple parent scopes, corresponding to the ISA scopes of the InstructionSets listed in the provides clause.
  • 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 CoreDef Y provides A, B, C), the parent scopes shall be traversed in the same order as given in the provides clause.
  • 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 {
        int<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
                int<32> local_A;
                // visible here: local_A + instruction scope
                if (field_A < 42) {
                    // nested block scope 1: local_AA + block scope
                    int<32> local_AA;
                } else {
                    // nested block scope 2: local_A + block scope
                    int<32> local_A; // shadows local_A from block scope
                }
                int<32> local_A2;
                // visible here: local_A, local_A2 + instruction scope
            }
        }
    }
    
    functions {
        void foo_A(int<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 {
        int<32> param_B;
    }
}
Clone this wiki locally