Deferred Shared Variables

Proposal Details

Current Situation

Defined in the analysis of VHDL2008 IR2119.

Requirement

Provides a methodology or mechanism that will permit a shared variable to be defined in the same package as the protected type.

Use Cases

See also 'Arguments For'.

Use Case: Shared Variable in Multiple Packages (Brent H)

My verification test benches often take the form as below:

               -----
  -------     |     |     -------
 | MDL_A |<-->|     |<-->| MDL_C |
  -------     |     |     -------
              | DUT |
  -------     |     |       -------
 | MDL_B |<-->|     |      | CNTRL |
  -------     |     |       -------
               -----

The models can be quite simple I/O functions to drive the DUT or quite complex BFMs.

The controller block has no physical connections to the DUT or models. It controls events via global signals and uses shared variables to set up the outputs of the models.

The shared variables are declared in packages belonging to each model, i.e. on a per model basis and requiring two packages per model.

So for the first protected type package might be:

  TYPE op_type_r IS
    RECORD
      output1_l : Std_Logic;
      output2_l : Std_Logic_Vector(2 DOWNTO 0);
      output3_l : Std_Logic;

    END RECORD op_type_r;

  TYPE op_type_pr IS
    PROTECTED

      IMPURE FUNCTION value_if
        RETURN op_type_r;

      PROCEDURE set_p (
        op_type_ri : op_type_r
        );

    END PROTECTED op_type_pr;

and then in the second package:

  -- initialize to value
  SHARED
    VARIABLE  op_init_rsv         : op_type_pr;

This approach allows me to initialize a models outputs, alter them during simulation or set them into error conditions in order to stimulate the DUT.

My problem is two packages per model instead of one, with the extra work involved in maintenance and the obvious difficulties in code comprehension with the declarations split across two files.

Use Case: Shared Variable References in Package (Jim L)

Once declared, shared variables can also be used in a package. In the following, the shared variable RV (randomization object) is used to randomly select an initialization for the signals GlobalInt and GlobalSlv.

 
  shared variable RV : RandomPType ;
  signal GlobalInt : integer := RV.RandInt(0, 255);
  signal GlobalSlv : std_logic_vector(1 downto 1) := RV.RandSlv(0,1,1) ;

Arguments FOR

a.

In my verification test benches, I often have shared variables defined on a model by model basis. This leads to each model requiring two packages; one for the shared variables and one for the protected types. It would simplify maintenance having one single package. My controlling block tends to be disconnected (physically) from the test bench, is driven from a TCL script and controls the simulation via shared variables and global signals. - BAH

Test Model Control Details:

The global signals provide simulation event (time) control of the various models and the shared variables are used to control their functionality.

My global signals are typically enumerated types e.g. (init_e, run_e, pause_e, end_e) used to control the status of the model.

My shared variables are normally record types of the model's output signals, used to control their values, with corresponding matching records of boolean types setting stuck-at and/or invert status of the respective signals. These boolean records allow for error conditions to be set on the model's outputs.

These shared variable formats are, by the nature of their record structure, specific to each model, which then require a package for their protected type definitions... thus two packages per model as opposed to one. - BAH

b.

It is something that new users would automatically think should be supported. - BAH

Implementation Candidates

Candidate 1: Deferred Shared Variables (Brent H)

Allow a shared variable to be declared in the same package as a protected type by providing a mechanism to defer the elaboration of the 'shared variable' until after the 'protected type body' has been elaborated (in the same package).

Add a new keyword 'deferred' to indicate that the 'shared variable' elaboration needs to be deferred until the 'package body' is elaborated.

Candidate 1: Code Examples

  package MY_PACKAGE is
    ... 
    type MY_PROTECTED_TYPE is 
      protected
        ... 
      end protected MY_PROTECTED_TYPE;

    shared variable MY_VARIABLE : MY_PROTECTED_TYPE deferred; 

  end package MY_PACKAGE;


  package body MY_PACKAGE is
    ... 
    type MY_PROTECTED_TYPE is 
      protected body
        ... 
      end protected body MY_PROTECTED_TYPE;

    shared variable MY_VARIABLE : MY_PROTECTED_TYPE; 

  end package body MY_PACKAGE;

Candidate 1: Other Syntax Considerations

As one of the aims of the group is to reduce the amount of proposed new keywords, the 'deferred' keyword could possibly be replaced by the 'postponed' keyword.

(However, to me, this doesn't seem to have the right syntactical sound and I would favour sticking with the 'deferred' keyword. - BAH)

The 'deferred' keyword could also be an additional option to the deferred 'constant' definition for uniformity.

Candidate 1: Global SIgnal Initial Values

The 'deferred' keyword could also be used to defer a (global) 'signal' initial value assignment which uses either a deferred 'shared variable' access method, a deferred 'constant' value, or a 'function' return value.

Candidate 1: Arguments AGAINST

This seems to be a significant change to VHDL's elaboration model.

Candidate 1: Language Concerns (CliffordWalinsky)

  1. I don't understand the utility of the new deferred (or even postponed) keyword. If the keyword is missing, that presumably means a shared variable of the protected type cannot be defined in the package header. Certainly, a compiler can check for the presence of a declared shared variable and the presence of the deferred keyword in the type definition. Except, I don't understand why one wouldn't want to always use the deferred keyword, once issues concerning elaboration of a shared variable within the body of the package have been addressed.

<Brent Hayhoe> For a constant, the omission of the expression assignment is normally defined as an error condition, except when used in the declarative part of a package. The omission here implies the constant as deferred and it is then assigned during elaboration of the package body. The main advantage of this is the ability to use functions, defined in the same package, within the expression assignment of the constant.

If we were to declare a global signal in a package and assign it an initial value using a function within the expression, without the 'deferred' keyword there is no way for the compiler to imply its deferred status. The omission of its initial value expression is quite valid and cannot be used to imply a deferred status.

For a shared variable, although we could imply a deferred status by the fact that its protected type is defined in the same package, it would seem to put more effort onto the compiler function rather than require the new 'deferred' keyword to explicitly define its deferred status. </Brent Hayhoe>

  1. The language standard should be expanded to explicitly state that elaboration of a protected type body shall occur during elaboration of the package body that contains it. Further, it needs to be explicitly stated that a design is erroneous if elaboration of a protected type body refers to a deferred constant or other shared variable that has not yet been elaborated.

Candidate 2: Allow Protected Type Bodies in Package Declaration Region (Jim L)

Allow a protected type body (and perhaps a subprogram body) to be included in a package declarative area. As a result, a shared variable could then be declared immediately after the protected type body - in an identical fashion to its use in an architecture declaration region. This use model would also make it similar to how other languages use classes.

The protected type body then would be the syntax that separates the public space of the protected type from the private space.

Arguments Against

Needs use cases not "Arguments For", so really cannot judge how important this is.

Email Reflector Comments

From: JimLewis (Mon Dec 17 2012 - 14:33:23 PST)

A use case that illustrates what your are trying to do and why would be helpful.

I am using protected types quite extensively, but I suspect that I am using them for a different purpose than you. Most of my shared variable declarations I use are private to an instance of a design and I declare them in the architecture declaration region.

Are you putting the shared variable declarations in a package to allow different instances (perhaps of the same design) to share a data structure?

Currently I am more limited by not allowing shared variables on interfaces and not allowing arrays of shared variables. I also need generics on protected types so I can effect an initializer.

From: MartinThompson (Tue Dec 18 2012 - 01:32:30 PST)

I read your DeferredSharedVariables page yesterday, wasn't aware of the history, so thanks for pointing me to that.

As with Jim, my use of shared variables is limited to "local" instances, so I haven't come across the problem - I would also appreciate an example of when you find this useful.

My immediate thought on reading your description was that, rather than introduce a 'deferment', can we not change things so that the "expected" behaviour actually happens? Is there a good reason for not being able to declare a shared variable in the same region as its type definition?

From: JonathanBromley (Tue Dec 18 2012 - 01:48:39 PST)

Brief comment from the sidelines by an interested but inactive observer:

I don't have as much experience in using protected types as I do with other kinds of OO-style programming, so I may be off track here, but... If a package provides some protected type as a service to the rest of your code, there may well be situations where the same package also should provide some "specimen" instances of that type - maybe as templates that help in the construction of new instances, maybe as predefined globally accessible objects (I could imagine that being useful, for example, for an objections mechanism).

It does seem perverse that you can't actually create one of the shared variables inside the package that defines their type. For example, in SystemVerilog I would find it very troublesome if I could not declare a package-level variable of a class type in the same package that defines the class.

From: JimLewis (Tue Dec 18 2012 - 09:25:29 PST)

One thing that differentiates VHDL from other languages is the division between protected type declaration and body. In addition within a package, the protected type body must be in the package body. Hence, in the package declarative region the protected type is not yet fully defined.

In the current language, I can make the following shared variable declaration and then use it. Should I be able to do this with "deferred" shared variables or should it be illegal? This would mean then that the elaboration of anything that references the shared variable also needs to be deferred.

   shared
      variable RV        : RandomPType ;
   signal      GlobalInt : integer                       := RV.RandInt(0, 255);
   signal      GlobalSlv : std_logic_vector(1 downto 1)  := RV.RandSlv(0,1,1) ;

The reason we need to see use models is that there may be less complicated solutions that acceptably solve the problem. What is the real problem? Having to put the shared variable in a different package or having more than one package reference.

One alternate solution could to allow a protected type body (and perhaps a subprogram body) to be included in a package declarative area. This then would make a shared variable use model identical to an architecture.

If the problem is having more than one package reference, then don't forget about the VHDL-2008 context clause.

From: Brent Hayhoe (Tue Dec 18 2012 - 09:25:29 PST)

I have put a few lines on the proposal page trying to explain how I use shared variables and the problems I have.

Looking at your example (below)above at first confused me, until I realised what you are doing (I think).

I presume that you are using the method sub-programs from the protected type to set the variable and use it to assign the initial values to the global signals.

I assume that if you had used functions and constants to achieve this, then the constants would have had to be deferred?

However, your point is well made and perhaps this shows that we may need to allow (global) signals to be deferrable as well? This would sync well into the language I think.

As to you suggestion whether we allow protected type bodies into the package declarative part, I do not know, but my gut instinct is probably no. However, I have to defer (pun?) to the language and compiler experts amongst us on this point.

From: TristanGingold - 2016-07-12

The example from Jim L is clearly invalid: RandInt cannot be called before being elaborated. One way to fix that (as suggested by Jim L) would be to allow protected bodies in package specification. That breaks a fundamental software engineering rule (spec vs impl), but why not.

I don't really like the addition of deferred reserved word. Furthermore, deferred declarations can create a lot of elaboration issue. What about allowing statements in a package body:

package body pkg is
   ...
begin
   --  Statements executed during elaboration of the package body.
   my_var := xxx;
end pkg;

That doesn't work with signal but I think this is not an important restriction.

Supporters

-- Brent Hayhoe - 2012-12-16

-- PatrickLehmann - 2016-07-18

Analysis

This proposal was discussed in the 2016 May 26th meeting under item 81 of the ranked proposals spreadsheet for VHDL-201x.

The requirement has similarities to deferred constants.

At least one HDL simulator vendor supports this (currently) non-standard functionality with a tool compiler switch, i.e. to solve the problem of a declaration of both a shared variable with its protected type within the same package.

The meeting decided that it would be better syntactically if the new reserved word deferred appeared at the beginning of the statement, becoming more like an object class modifier.

The new reserved word deferred can now be used as an alternative to omitting the value assignment in a constant declaration, in order to allow the same delayed value assignment functionality for its initial value expression.

The new reserved word deferred can also be used in a signal declaration in order to allow the same delayed value assignment functionality for its initial value expression as that of a deferred constant.

The new reserved word deferred can also be used in a 'normal' variable declaration (when associated with a non-protected type) in order to allow the same delayed value assignment functionality for its initial value expression as that of a deferred constant. A variable, when associated with a protected type, can also be deferred in order to allow its analysis to be delayed similarly to that of a deferred shared variable.

Italic prefixes in BNF productions are used to impart extra semantic information where a complete definition of the BNF production is either not possible or too complex to construct. This 'extra' information is detailed within the associated LRM text. The 'subtype indication' BNF symbols used within the BNF expressions in various BNF productions already include such italic prefixes and the existing BNF symbol occurrences are further expanded in order to enhance semantic information.

In the 2016 November 24th meeting it was decided to split this LCS into two (LCS-2016-080a & LCS-2016-080b) in order to separate out this last point from the main proposal for the sake of clarity.

Package Declarations

A package may be declared in a number of different places within the VHDL code structure, along with its package body (if required). The most common of these is as a separate design unit and its declared items referenced via a use clause.

Because this kind of package can be referenced by concurrent code, it must not declare a normal variable within its package declaration. However a shared variable can be declared here. Similarly, a signal may also be declared here and is often referred to as a global signal, because of the ability for it to be made visible anywhere by a use clause.

A package may also be declared in a number of other code structure declarative regions.

When a package is declared within the declarative regions of an entity, an architecture, or a block, the same concurrent code restrictions apply as those of a primary design unit specified above.

A package may also be declared within the declarative regions of a process, a subprogram, or a protected body of a protected type and, because these structures define sequential code, the reverse declaration rules apply. In these areas a normal variable may be declared, but neither a shared variable nor a signal declaration is allowed.

A package may also be declared within a package declaration or a package body. In these cases, the declarative rules for a variable, shared variable and signal are defined by those of its parent package declaration.

The deferred versions of these object classes follow the same declarative rules, but may only be declared within a package declaration and its full declaration must appear within the associated package body.

Deferred Constants

If we wish to define a function plus a constant in the same package and in so doing we want to use the function to define the value of the constant then the value cannot be assigned in the package declaration because at this point in the analysis phase it knows nothing about the body of the function.

   package my_package is
      function my_function(a, b : integer) return my_signed_type;
      constant my_constant : my_signed_type;                            -- deferred constant
   end package my_package;

If we just move the constant declaration to the package body (after the function body) the problem is resolved. However, the constant cannot now be made visible (by a use statement) outside the scope of the package.

In order to overcome this problem, the value assignment of the constant in the package declaration is omitted and this defines the object as a deferred constant giving visibility to the constant assigned in the package body.

   package body my_package is
      function my_function(a, b : integer) return my_signed_type is
      begin
         ...
      end function my_function;
      constant my_constant : my_signed_type := my_function(1, 2);       -- constant value
   end package my_package;                                              --          assigned

The constant declaration is repeated in the package body (after the function body) with the value assignment included.

Deferred Shared Variables

If we wish to define a protected type plus a shared variable in the same package there is a similar problem.

The shared variable cannot be declared in the package declaration because at this point in the analysis phase it knows nothing about the body of the protected type and its methods and local variable(s), only the declaration of the methods.

   package my_package is
      type my_protected_type is protected
         function get return my_signed_type;
         procedure set(value : my_signed_type);
      end protected my_protected_type;
      deferred shared variable my_shared_variable : my_protected_type;  -- deferred shared
                                                                        --          variable
   end package my_package;

If we just move the shared variable declaration to the package body (after the protected type body) the problem is resolved. However, the shared variable cannot now be made visible (by a use statement) outside the scope of the package.

The work-around is to declare the shared variable in a second package which 'uses' this package.

   package body my_package is
      type my_protected_type is protected body
         variable local : my_signed_type;
         function get return my_signed_type is
         begin
            ;
         end function get;
         procedure set(value : my_signed_type);
         begin
            ;
         end procedure set;
      end protected my_protected_type;
      shared variable my_shared_variable : my_protected_type;           -- analysed shared
                                                                        --          variable
   end package my_package;

A better solution to overcome this problem is to delay the analysis of the shared variable to the body of the package, but unlike deferred constant a new keyword - deferred - is added after the subtype indication giving visibility to the shared variable declared in the package body.

Deferred Non-Shared Variables

A normal non-shared variable can also be associated with a protected type, giving two forms of a deferred variable; first, allowing a function call in the initialization expression (similar to a deferred constant); second, allowing a variable of a protected type to be declared in the same package as its protected type declaration and body (similar to a deferred shared variable).

   package my_package is
      function my_function(a, b : integer) return my_signed_type;
      type my_protected_type is protected
         function get return my_signed_type;
         procedure set(value : my_signed_type);
      end protected my_protected_type;
      deferred variable my_variable1 : my_signed_type;                  -- deferred variable
      deferred variable my_variable2 : my_protected_type;               -- deferred variable
   end package my_package;

Both variable's 'deferred' declarations appear in the package body.

   package body my_package is
      function my_function(a, b : integer) return my_signed_type is
      begin
         ...
      end function my_function;
      type my_protected_type is protected body
         variable local : my_signed_type;
         function get return my_signed_type is
         begin
            ;
         end function get;
         procedure set(value : my_signed_type);
         begin
            ;
         end procedure set;
      end protected my_protected_type;
      variable my_variable1 : my_signed_type := my_function(1, 2);      -- variable initial
                                                                        --     value defined
      variable my_variable2 : my_protected_type;                        -- analysed variable
   end package my_package;

Deferred Signals

If we wish to define a function plus a global signal in the same package and in so doing we want to use the function to initialize the value of the global signal then this now becomes possible.

   package my_package is
      function my_function(a, b : integer) return my_signed_type;
      deferred signal my_global_signal : my_signed_type;                -- deferred global
                                                                        --            signal
   end package my_package;

We can now delay the analysis of the global signal to the body of the package using the new keyword - deferred.

   package body my_package is
      function my_function(a, b : integer) return my_signed_type is
      begin
         ...
      end function my_function;
      signal my_global_signal : my_signed_type := my_function(1, 2);    -- global signal
   end package my_package;                                              --     initial value
                                                                        --           defined

BNF Productions

Object Class Productions

constant_declaration ::=
     normal_constant_declaration
   | deferred_constant_declaration

normal_constant_declaration ::=
     constant identifier_list : constant_subtype_indication := expression ;

deferred_constant_declaration ::=
     [ deferred ] constant identifier_list : constant_subtype_indication ;

variable_declaration ::=
     local_variable_declaration
   | shared_variable_declaration

local_variable_declaration ::=
     normal_variable_declaration
   | deferred_variable_declaration

normal_variable_declaration ::=
     variable identifier_list : nonprotected_subtype_indication [ := expression ] ;
   | variable identifier_list : protected_subtype_indication ;

deferred_variable_declaration ::=
     deferred variable identifier_list : subtype_indication ;

shared_variable_declaration ::=
     normal_shared_variable_declaration
   | deferred_shared_variable_declaration

normal_shared_variable_declaration ::=
     shared variable identifier_list : protected_subtype_indication ;

deferred_shared_variable_declaration ::=
     deferred shared variable identifier_list : protected_subtype_indication ;

signal_declaration ::=
     normal_signal_declaration
   | deferred_signal_declaration

normal_signal_declaration ::=
     signal identifier_list : signal_subtype_indication [ signal_kind ] [ := expression ] ;

deferred_signal_declaration ::=
     deferred signal identifier_list : signal_subtype_indication [ signal_kind ] ;

file_declaration ::=
     file identifier_list : file_subtype_indication [ file_open_information ] ;

Interface Object Class Productions

interface_constant_declaration ::=
     [ constant ] identifier_list : [ in ] constant_subtype_indication [ := static_expression ]

interface_variable_declaration ::=
     [ variable ] identifier_list : [ mode ] nonprotected_subtype_indication [ := static_expression ]
   | [ variable ] identifier_list : inout protected_subtype_indication

interface_signal_declaration ::=
     [ signal ] identifier_list : [ mode ] signal_subtype_indication [ bus ] [ := static_expression ]

interface_file_declaration ::=
     file identifier_list : file_subtype_indication

Package Declarative Items

package_declarative_part ::=
     { general_package_declarative_part }
   | { concurrent_package_declarative_part }
   | { sequential_package_declarative_part }

general_package_declarative_part ::=
     general_package_declarative_item

concurrent_package_declarative_part ::=
     general_package_declarative_item
   | concurrent_package_declarative_item

sequential_package_declarative_part ::=
     general_package_declarative_item
   | sequential_package_declarative_item

general_package_declarative_item ::=
     subprogram_declaration
   | subprogram_instantiation_declaration
   | package_declaration
   | package_instantiation_declaration
   | nonprotected_type_declaration
   | subtype_declaration
   | protected_type_declaration
   | normal_constant_declaration
   | deferred_constant_declaration
   | file_declaration
   | alias_declaration
   | component_declaration
   | attribute_declaration
   | attribute_specification
   | use_clause
   | group_template_declaration
   | group_declaration

concurrent_package_declarative_item ::=
     normal_signal_declaration
   | deferred_signal_declaration
   | normal_shared_variable_declaration
   | deferred_shared_variable_declaration
   | disconnection_specification
   | PSL_Property_Declaration
   | PSL_Sequence_Declaration

sequential_package_declarative_item ::=
     normal_variable_declaration
   | deferred_variable_declaration

Package Body Declarative Items

package_body_declarative_part ::=
     { general_package_body_declarative_part }
   | { concurrent_package_body_declarative_part }
   | { sequential_package_body_declarative_part }

general_package_body_declarative_part ::=
     general_package_body_declarative_item

concurrent_package_body_declarative_part ::=
     general_package_body_declarative_item
   | concurrent_package_body_declarative_item

sequential_package_body_declarative_part ::=
     general_package_body_declarative_item
   | sequential_package_body_declarative_item

general_package_body_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | package_declaration
   | package_body
   | package_instantiation_declaration
   | nonprotected_type_declaration
   | subtype_declaration
   | protected_type_declaration
   | protected_type_body
   | normal_constant_declaration
   | file_declaration
   | alias_declaration
   | attribute_declaration
   | attribute_specification
   | use_clause
   | group_template_declaration
   | group_declaration

concurrent_package_body_declarative_item ::=
     normal_signal_declaration
   | normal_shared_variable_declaration

sequential_package_body_declarative_item ::=
     normal_variable_declaration

Other Structures

Design Unit Declarative Items
library_unit ::=
     primary_unit
   | secondary_unit

primary_unit ::=
     entity_declaration
   | configuration_declaration
   | nonsequential_package_declaration
   | nonsequential_package_instantiation_declaration
   | context_declaration
   | PSL_Verification_Unit

secondary_unit ::=
     architecture_body
   | nonsequential_package_body

Entity Declarative Items
entity_declarative_part ::=
     { entity_declarative_item }

entity_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | nonsequential_package_declaration
   | nonsequential_package_body
   | nonsequential_package_instantiation_declaration
   | type_declaration
   | subtype_declaration
   | normal_constant_declaration
   | normal_signal_declaration
   | normal_shared_variable_declaration
   | file_declaration
   | alias_declaration
   | attribute_declaration
   | attribute_specification
   | disconnection_specification
   | use_clause
   | group_template_declaration
   | group_declaration
   | PSL_Property_Declaration
   | PSL_Sequence_Declaration
   | PSL_Clock_Declaration

Architecture and Block Declarative Items
architecture_declarative_part ::=
     { block_declarative_item }

block_declarative_part ::=
     { block_declarative_item }

block_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | nonsequential_package_declaration
   | nonsequential_package_body
   | nonsequential_package_instantiation_declaration
   | type_declaration
   | subtype_declaration
   | normal_constant_declaration
   | normal_signal_declaration
   | normal_shared_variable_declaration
   | file_declaration
   | alias_declaration
   | component_declaration
   | attribute_declaration
   | attribute_specification
   | configuration_specification
   | disconnection_specification
   | use_clause
   | group_template_declaration
   | group_declaration
   | PSL_Property_Declaration
   | PSL_Sequence_Declaration
   | PSL_Clock_Declaration
Subprogram Declarative Items
subprogram_declarative_part ::=
     { subprogram_declarative_item }

subprogram_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | nonconcurrent_package_declaration
   | nonconcurrent_package_body
   | nonconcurrent_package_instantiation_declaration
   | type_declaration
   | subtype_declaration
   | normal_constant_declaration
   | normal_variable_declaration
   | file_declaration
   | alias_declaration
   | attribute_declaration
   | attribute_specification
   | use_clause
   | group_template_declaration
   | group_declaration
Protected Type Body Declarative Items
protected_type_body_declarative_part ::=
     { protected_type_body_declarative_item }

protected_type_body_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | nonconcurrent_package_declaration
   | nonconcurrent_package_body
   | nonconcurrent_package_instantiation_declaration
   | type_declaration
   | subtype_declaration
   | normal_constant_declaration
   | normal_variable_declaration
   | file_declaration
   | alias_declaration
   | attribute_declaration
   | attribute_specification
   | use_clause
   | group_template_declaration
   | group_declaration
Process Declarative Items
process_declarative_part ::=
     { process_declarative_item }

process_declarative_item ::=
     subprogram_declaration
   | subprogram_body
   | subprogram_instantiation_declaration
   | nonconcurrent_package_declaration
   | nonconcurrent_package_body
   | nonconcurrent_package_instantiation_declaration
   | type_declaration
   | subtype_declaration
   | normal_constant_declaration
   | normal_variable_declaration
   | file_declaration
   | alias_declaration
   | attribute_declaration
   | attribute_specification
   | use_clause
   | group_template_declaration
   | group_declaration
Topic revision: r50 - 2020-02-17 - 15:34:29 - JimLewis
 
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback