Variable is an object with a single current value.
variable variable_name : type;
variable variable_name : type := initial_value;
Variables are objects which store information local to processes and subprograms (procedures and functions) in which they are defined. Their values can be changed during simulation through the variable assignment statements.
A variable declaration includes one or more identifiers, a subtype indication and an optional globally static expression defining the initial value for the variable(s). The identifiers specify names for the variables, with one identifier per each variable. The variable can be declared to be of any type or subtype available, either constrained or unconstrained (Example 1).
The initial value of a variable can be assigned by a globally static expression. The expression must reference a value of the same type as the variable itself. If the variable is declared to be of a composite type other than a string, Bit_Vector or Std_Logic_Vector, then an aggregate must be used (see Example 2).
If the initial value of a variable is not specified, then it is implicitly set as the left bound of the type used. For example for a scalar named T, the default initial value will be T'LEFT. For a composite type, the initial value will be the aggregate consisting of the set of the default values of all the scalar elements. The default initial value for a variable of the access type is null.
Variables declared in processes are initialized with their default values, given either explicitly or implicitly, at the start of the simulation. Variables declared in subprograms are initialized each time the subprogram is called.
The scope of variables is limited to the process or subprogram they are defined in. The only exception to this rule is a shared variable, which may be shared by multiple processes.
Variables can be also declared outside of a procedure or process to be shared between many processes. Shared variables may be declared within an architecture, block, generate statement or package. Declaration of a shared variable must be preceded by the shared keyword (Example 3).
Although the Language Reference Manual allows several processes to access a single shared variable it does not define what happens when two or more conflicting processes try to access the same variable at the same time. Such a situation may lead to unpredictable results and therefore should be avoided.
Example 1
type Mem is array
(Natural range <>,
Natural range <>) of Std_Logic;
variable Delay1, Delay2 : Time;
variable RAM1: Mem (0 to
1023, 0 to 8);
The type Mem is specified as an unconstrained memory (the limit
depends on the implementation of the Natural subtype). The variable
RAM1, specified in the third line, is based on the Mem type and is
defined as a subtype constrained to a 1 KB memory.
Both Delay1 and Delay2 variables are of the Time type and are declared in the second line.
Example 2
type Mem is array
(Natural range <>,
Natural range <>) of Std_Logic;
variable TempCond : Boolean
:= true;
variable RAM2: Mem (0 to
7, 0 to 7):=
(('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'),
('0', '0', '0', '0', '0', '0', '0', '0'));
Both variables are initialized according to the types used. Note the
aggregate has been used for initializing RAM2, which is an 88 bit memory.
Example 3
shared variable FreeAccess : Boolean := true;
The shared variable FreeAccess
statement is used to determine whether a shared resource can be
accessed at any particular time. However, in real applications a
signal declaration would better serve for this purpose because using signals
makes the specification more deterministic.
Unlike signals, variables have neither history nor future, because according to its definition, each variable has only current value. No checking for the last event, time elapsed since the last event, previous value, etc. can be performed on variables.
The non-shared variables are limited to subprograms and processes only.
If a value of a variable is read before it is assigned in a clocked process (i.e. where operations are performed when an edge of clock signal is detected) then a register will be synthesized for this variable. A similar situation inside a combinatorial process may lead to generation of a latch.
Variables declared in a subprogram are synthesized as combinatorial logic.
During simulation variables consume a lot less (even an order of magnitude) memory space than signals. Therefore, it is highly recommended to use them for storage elements (such as memories) instead of signals.
Shared variables may cause a system to be non-deterministic and therefore they should be avoided.