Variables
Like wires, variables are named containers for values that always maintain their state (the value is retained until overwritten). They can only be given a value when declared or in an initial, always, or analog process. If given a value in an analog process they are referred to as continuous variables, meaning that they are owned and managed by the continuous kernel. Otherwise they are referred to as discrete variables and are owned and managed by the discrete kernel.
Continuous variables are not supported in Verilog, and discrete variables are not supported in Verilog-A.
Discrete variables may be initialized when declared, and initially take the value of x if not initialized. Continuous variables may not be initialized and always start off as 0.
Variables retain their value until changed by way of an assignment statement.
Registers
A register or reg declaration declares arbitrarily sized logic variables (registers are not supported in Verilog-A). The default size is one bit.
Examples:
reg enable;
reg [15:0] in;
In these examples, enable is a one bit variable and in is a 16 bit variable. The index of the most significant bit is given first in the range specification, and the index of the least significant bit is given last. The bounds must be constants (derived from number literals or parameters).
By default the content of multi-bit registers are interpreted as unsigned numbers (the values are interpreted as positive binary numbers). It is possible to explicitly specify whether the number is to be interpreted as a signed or unsigned number as follows:
reg unsigned [3:0] gain;
reg signed [6:0] offset;
In this case, gain is unsigned and offset is signed, which means it is interpreted as a twos-complement signed number. So, if gain = 4’bF, its value is interpreted as 15, and if offset = 7’b7FF, then its value is interpreted as -1.
Integer Variables
An integer declaration declares one or more variables of type integer. These variables can hold values ranging from -231 to 231-1. Arithmetic operations performed on integer variables produce 2’s complement results. Integers are initialized at the start of a simulation depending on how they are used. Integer variables whose values are assigned in an analog process default to an initial value of zero (0). Such variables are said to be captured by the analog kernel. Integers that are captured by the analog kernel cannot be initialized and can only hold valid numbers (they may not contain any x- or z-valued bits). Integer variables whose values are assigned in a digital context default to an initial value of x. These variables are said to be captured by the discrete kernel. Such integers are implemented as 32-bit signed regs. As such, the values they hold may contain bits that are x or z.
Example:
integer count, ub = 15;
Integer variables can only be given a value using an assignment statement, which can only be found in its declaration or in initial, always, and analog processes.
GenVars
A type of integer, genvar, has restricted semantics that allow it to be used in static expressions. A genvar can only be assigned within the control section of a for loop. Assignments to the genvar variable can consist only of expressions of static values (expression involving only parameters, literal constants, and other genvar variables).
- Example::
genvar i;
Real Variables
A real declaration declares one or more variables of type real. The real variables are stored as 64-bit quantities, as described by IEEE STD-754-1985, an IEEE standard for double precision floating point numbers. Real variables are initialized to zero (0) at the start of a simulation.
Example:
real save, midpoint;
Real variables can only be given a value using an assignment statement, which can only be found in its declaration or in initial, always, and analog processes. Real variables assigned in analog processes are captured by the analog kernel and their value is assumed to vary continuously with time. All other real variables are captured by the discrete kernel and their values are piecewise constant.
Named Events
Events are normally associated with changes in discrete-event signals, but it is also possible to declare a variable that does not actually hold a value, but it is capable to trigger event statements. To declare a named event, use:
event failure;
Named events are triggered using ‘->’ in an initial or always process. For example:
-> failure;
The event can now be caught in an initial or always process using:
@(failure) begin
$strobe("Failure detected");
failures = failures + 1;
end
Arrays
Arrays of registers, integers and reals can be declared using a range that defines the upper and lower indices of the array. Both indices are specified with constant expressions that may evaluate to a positive integer, a negative integer, or to zero.
Examples:
reg [7:0] mem [1023:0];
integer i, weights[7:0] = {2, 4, 8, 16, 32, 64, 128, 256};
real in1[15:0], in2[15:0], out[15:0];
An array of registers is often referred to as a memory. In the example, mem is an array of 1024 bytes (8-bit values). One would use mem[i] to access a particular byte and mem[i][j] to access a particular bit of the same byte.