System Verilog Static Class and members


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: