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
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.
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
Here is a static task example
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
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
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
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. :)
Feel free to inform us about any mistakes in the post. :)
Video is blurry .
ReplyDeleteVideo has been replaced by animation
ReplyDelete