Data Declaration in  System Verilog

Welcome to the System Verilog tutorial series! If you have any doubts / suggestions, please let us know!  Dear visitor, please Sign up / Login for Free and get privileged access! You can copy code, download free tutorials and do more when you’re logged in!

Scope And Lifetime:


SystemVerilog adds the concept of global scope. Any declarations and definitions which is declared outside a module, interface, task, or function, is global in scope. Global variables have a static lifetime (exists for the whole elaboration and simulation time). Datatypes, tasks,functions, class definitions can be in global scope. Global members can be referenced explicitly via the $root . All these can be accessed from any scope as this is the highest scope and any other scope will be below the global.


Local declarations and definitions are accessible at the scope where they are defined and below. By default they are static in life time. They can be made to automatic. To access these local variables which are static, hierarchical pathname should be used.

int st0; //Static. Global Variable. Declared outside module
task disp(); //Static. Global Task.
module msl;
int st0; //static. Local to module
initial begin
int st1; //static. Local to module
static int st2; //static. Local to Module
automatic int auto1; //automatic.
task automatic t1(); //Local task definition.
int auto2; //automatic. Local to task
static int st3; //static.Local to task. Hierarchical path access allowed
automatic int auto3; //automatic. Local to task
$root.st0 = st0; //$root.sto is global variable, st0 is local to module.


The Verilog assign statement is a unidirectional assignment. To model a bidirectional short-circuit connection it is necessary to use the alias statement.This example strips out the least and most significant bytes from a four byte bus:

module byte_rip (inout wire [31:0] W, inout wire [7:0] LSB, MSB);
alias W[7:0] = LSB;
alias W[31:24] = MSB;

Data Types On Ports:

Verilog restricts the data types that can be connected to module ports. Only net types are allowed on the receiving side and Nets, regs or integers on the driving side. SystemVerilog removes all restrictions on port connections. Any data type can be used on either side of the port. Real numbers, Arrays, Structures can also be passed through ports.

Parameterized Data Types:

Verilog allowed only values to be parameterized. SystemVerilog allows data types to be “parameterized”. A data-type parameter can only be set to a data-type.

module foo #(parameter type VAR_TYPE = integer);
foo #(.VAR_TYPE(byte)) bar ();

Declaration And Initialization:

integer i = 1;

In Verilog, an initialization value specified as part of the declaration is executed as if the assignment were made from an initial block, after simulation has started. This creates an event at time 0 and it is same as if the assiginment is done in initial block. In Systemverilog , setting the initial value of a static variable as part of the variable declaration is done before initial block and so does not generate an event.


Historically, Verilog used the terms wire and reg as a descriptive way to declare wires and registers. The original intent was soon lost in synthesis and verification coding styles, which soon gave way to using terns Nets and Variables in Verilog-2001. The keyword reg remained in SystemVerilog, but was now misleading its intent. SystemVerilog adds the keyword logic as a more descriptive term to remind users that it is not a hardware register. logic and reg are equivalent types.

SystemVerilog extended the variable type so that, it can be used to connect gates and modules. All variables can be written either by one continuous assignment, or by one or more procedural statements. It shall be an error to have multiple continuous assignments or a mixture of procedural and continuous assignments.

Now we saw logic and wire are closer. Wire (net) is used when driven by multiple drivers, where as logic is used when it is driven by only one driver. logic just holds the last value assigned to it, while a wire resolves its value based on all the drivers.

For example:

logic abc;

The following statements are legal assignments to logic abc:
1) assign abc = sel ? 1 : 0;
2) not (abc,pqr),
3) always #10 abc = ~abc;