System Verilog Static Class and members

2 comments :

System Verilog Static Class Members

When we want to have some variable which we do not want to change its value across whole program and within all instances then static members come in action.
Let us take an example like a counter which will count how many times a particular class was instantiated then it is obvious that we ought to have that counter variable value to be on hold and not to get initialized or reset whenever a particular class in instantiated. At this point static member of a class comes in action.
There are two ways by which we can count the instantiation of the class as well as it’s functions and task.

The first method to calculate how many times a particular task has been called
By using simple task function and calling it and declaring a static variable in the class. 
Here is an example

class Static;
  static integer n=0;
  task calling;
    n++;
    $strobe("The task calling has been called %d times",n);
    endtask:calling
endclass:Static
 
module test;
  initial begin
  Static x = new;
  Static y = new;
  Static z = new;
  z.calling();  //n=1
  x.calling();  //n=2
  x.calling();  //n=3
  y.calling();  //n=4
end
endmodule


Notice that the variable is static and the task calling has been called two times. First by x.callling and second be z.calling hence we get this output

The simulator used here is Questasim 10b

But this didn’t give us the report about how many times the particular class has been instantiated. We have called the class Static here three times hence to calculate we have to create a strict function.

The function’s name will be new and it cannot be changed. This new function is basically the constructor which is called every time whenever a class is instantiated.
The arguments of the function or constructor can remain empty or one may also pass arguments to the constructor.

Here is its code

class Static;
  static integer n=0;
  function new();
    n++;
  endfunction
  task calling;
    $strobe("The static class has been called %d times",n);
    endtask:calling
endclass:Static
 
module test;
  initial begin
  Static x = new;  //n=1 The function new gets activated 
  Static y = new;  //n=2
  Static z = new;  //n=3
  z.calling();
end
endmodule
and here is its output


 Static Methods Functions and Tasks



When a task or function is declared as static by placing the keyword static before the keyword task and function then the particular function and task becomes static in nature. There are certain rules about static tasks and functions.

A static task or function can only call a static variable and not a non static variable. A non-static task  however can call static as well as non static member of the particular class.

Here is the error (along with code) when a static task tries to call a non-static variable


The error lies in line 10 and 11 where the task calling tries to access the non-static member of the class.

In terms of the function new this is fascinating because a static new function known as constructor does not show error when a non static member of class is called within it. As we can see in image above at line 6 the non static variable has been called and no error report has been generated. Thus a constructor can call static as well as a non-static class member

NOTE- Only the constructor function supports this. A random function will certainly show error

Thus a static as well as non-static constructor can access static as well as non static variable.

Check this out.

class Static;
  static integer n=0;
  integer z=0;
  static function new();  //CONSTRUCTOR
    n++;
    z++;
    $strobe("The value of n is%d and of z is%d",n,z);
  endfunction
endclass:Static
 
module test;
  initial begin
  Static x = new; //Constructor Call
  Static y = new;
  Static z = new;
end
endmodule


The output


Since the variable z is not static hence each instantiation has its value as 0 which is not the case with variable n which is static.
Here the function is static which is calling a non static member.

Declaring the member z as static gives this as output


Changing the constructor to a normal function would result an error as show in this animation.


Here is a static task example 

class Static;
  static integer n=0;
  static integer z=0;
  static integer call=0;
  static function new();
    n++;
    z++;
    $strobe("The value of n is%d and of z is%d",n,z);
  endfunction
  static task calling;
  call++;
    $strobe("This task has been called%d times",call);
  endtask:calling
endclass:Static

module test;
  initial begin
  Static x = new;
  Static y = new;
  Static z = new;
  x.calling();
  x.calling();
  z.calling();  
  x.calling();
  x.calling();
  z.calling();
  x.calling();
  x.calling();
  z.calling();
  x.calling();
  x.calling();
  z.calling();
end
endmodule



Here is its output


Here is an example showing the non-constructor execution.
Conclusion - A constructor can access static as well as non static members. A static function or task cannot access a non-static member.

Constant class and its members


In System Verilog we have constant variables whose value cannot be changed since declared as constant. However only two modes of variable declaration is allowed. The first is
  • Global Constant
  • Class Instance called Constant
The Global Constant has a certain value assigned predefined whereas in Class Instance Constant the values are not assigned and can be assigned only once but only in constructor of the class.

Here is the code to show the error related to Constant Integer

class Static;
  const integer n=10;
  const integer z;
  
  function new();
    z=20;
    $strobe("The value of n is%d and of z is%d",n,z);
  endfunction
  task tas;
    n++;            //ERROR HERE
  endtask:tas
endclass:Static

module test;
  initial begin
  Static x = new;
  x.tas();
end
endmodule

And here is the error while compiling this code in Questasim.


Thus n as declared here cannot be incremented as it is a Constant.

In the following example I have declared a function which shows the same behavior as task. Any constant cannot be either assigned or modified.

class Static;
  const integer n=10;
  const integer z;
  
  function abc();
    this.n++;
    z=20;
    z++;
    $strobe("The value of n is%d and of z is%d",n,z);
  endfunction
endclass:Static

module test;
  initial begin
  Static x = new;
  x.abc();
end
endmodule


However there is a solution to overcome this issue of constant integer and that is constructor. A constant variable can be changed by the constructor function. It can be modified as well as assigned n number of times. Any function except the constructor cannot change or assign the values of a const integer.

Here is the code using constructor and modifying the constant values

class Static;
  const integer n=10;
  const integer z;
  
  function new();
    this.n++;
    z=20;
    z++;
    $strobe("The value of n is%d and of z is%d",n,z);
  endfunction
endclass:Static

module test;
  initial begin
  Static x = new;
end
endmodule

Here is the Output with successful compilation with output values of n and z


Conclusion - A constructor allows calling of a non-static class member. It can change the value of a Constant integer as well as can assign it.

Feel free to inform us about any mistakes in the post. :)

2 comments :