Data Declarations

There are several forms of data in SystemVerilog: literals, parameters, constants, variables, nets, and attributes
Constants are literals, genvars parameters, localparams, and specparams.
Variables must be written by procedural statements, and nets must be written by continuous assignments or ports.
SystemVerilog extends the functionality of variables by allowing them to either be written by procedural statements or driven by a single continuous assignment, similar to a wire. Since the keyword reg no longer describes the user’s intent in many cases, the keyword logic is added as a more accurate description that is equivalent to reg.

SystemVerilog requires data to be declared before it is used, apart from implicit nets. The rules for implicit nets are the same as in Verilog-2001.

A variable can be static (storage allocated on instantiation and never de-allocated) or automatic (stack storage allocated on entry to a scope (such as a task, function or block) and de-allocated on exit). SystemVerilog follows Verilog with respect of the static default storage class, with automatic tasks and functions, but allows static to override a default of automatic for a particular variable in such tasks and functions.


Constants are named data variables that never change. There are three kinds of constants, declared with the keywords localparam, specparam, and const.

localparam byte colon1 = ":" ;
specparam int delay = 10 ; // specparams are used for specify blocks
const logic flag = 1 ;

A parameter or local parameter can only be set to an expression of literals, parameters or local parameters, genvars, enumerated names, or a constant function of these. Hierarchical names are not allowed.
A specparam can also be set to an expression containing one or more specparams.

A static constant declared with the const keyword can only be set to an expression of literals, parameters, local parameters, genvars, enumerated names, a constant function of these, or other constants. The parameters, local parameters or constant functions can have hierarchical names because constants declared with the const keyword are calculated after elaboration. An automatic constant declared with the const keyword can be set to any expression that would be legal without the const keyword.

const logic option = a.b.c ;

A constant expression contains literals and other named constants.
An instance of a class (an object handle) can also be declared with the const keyword.

const class_name object = new(5,3);

This means that the object acts like a variable that cannot be written. The arguments to the new method must be constant expressions. The members of the object can be written (except for those members that are declared const).

SystemVerilog enhancements to parameter and localparam constant declarations. SystemVerilog does not change specparam constants declarations. A const form of constant differs from a localparam constant in that the localparam must be set during elaboration, whereas a const can be set during simulation, such as in an automatic task.


A variable declaration consists of a data type followed by one or more instances.

shortint s1, s2[0:9];

A variable can be declared with an initializer, for example:

int i = 0;

In Verilog-2001, an initialization value specified as part of the declaration is executed as if the assignment were made from an initial block after the simulation has started. Therefore, the initialization can cause an event on that variable at simulation time zero.

In SystemVerilog, setting the initial value of a static variable as part of the variable declaration (including static class members) shall occur before any initial or always blocks are started, and so does not generate an event. If an event is needed, an initial block should be used to assign the initial values.

Initial values in SystemVerilog are not constrained to simple constants; they can include run-time expressions, including dynamic memory allocation. For example, a static class handle or a mailbox can be created and initialized by calling its new method, or static variables can be initialized to random values by calling the $urandom system task. This requires a special pre-initial pass at run-time.

The default values for SystemVerilog variables are:

4 state integral:   ’x
2 state integral:   ’0
real, shortreal:     0.0
Enumeration:      First value in the enumeration
string:        “” (empty string)
event:         New event
class:       Null

Scope and lifetime

Any data declared outside a module, interface, task, or function, is global in scope (can be used anywhere after its declaration) and has a static lifetime (exists for the whole elaboration and simulation time).

SystemVerilog data declared inside a module or interface but outside a task, process or function is local in scope and static lifetime (exists for the lifetime of the module or interface).

Data declared in an automatic task, function, or block has the lifetime of the call or activation and a local scope.

Data declared in a static task, function, or block defaults to a static lifetime and a local scope.

Verilog-2001 allows tasks and functions to be declared as automatic, making all storage within the task or function automatic. SystemVerilog allows specific data within a static task or function to be explicitly declared as automatic. Data declared as automatic has the lifetime of the call or block, and is initialized on each entry to the call or block. The lifetime of a forkjoin, forkjoin_any, or forkjoin_none block shall encompass the execution of all processes spawned by the block. The lifetime of a scope enclosing any forkjoin block includes the lifetime of the forkjoin block.

SystemVerilog also allows data to be explicitly declared as static. Data declared to be static in an automatic task, function or block has a static lifetime and a scope local to the block.

module msl;
int st0; // static
initial begin
int st1; //static
static int st2; //static
automatic int auto1; //Automatic
task automatic t1();
int auto2; //Automatic
static int st3; //static
automatic int auto3; //Automatic

SystemVerilog adds an optional qualifier to specify the default lifetime of all variables declared in a task, function, or block defined within a module, interface, or program. The lifetime qualifier is automatic or static. The default lifetime is static.

program automatic test ;
int i; // not within a procedural block - static
task foo( int a ); // arguments and variables in foo are automatic

Class methods and declared for loop variables are by default automatic, regardless of the lifetime attribute of the scope in which they are declared.
Note that automatic or dynamic variables cannot be written with nonblocking or continuous assignments.
Automatic variables and dynamic constructs—object handles, dynamic arrays, associative arrays, strings, and event variables—shall be limited to the procedural context.

<< Previous | Next >>