Showing posts with label Classes. Show all posts
Showing posts with label Classes. Show all posts

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. :)

                System Verilog Class and Objects



                System Verilog Classes and Objects 


                A class is a blueprint or schematic which has its own behavior and works the same way for different instantiations. Any variable which is called or “instantiated” with the blueprint of this class is called an object of this class. Object Orientation revolves around classes and objects. It’s like solar system where the sun is OOPS and planets are class, objects, subclass, class variables, subclass variables etc.

                Explaining by example – We all know about int command in C. The command is like
                int x = 0 ;  int y = 1 ;

                So somewhere there is a class with definition “int” and x and y here are objects instantiated with “int” class. So each object has access to the properties of int and no interference takes place within the objects, i.e. here x and y do not have interference although both have the same class. It is like you and you friend buy different biscuits from the same shop. Now each class can have a subclass. This forms a hierarchy.

                The basic class definition is like this:

                class <class_name>;
                            ///Properties
                            ///Method
                endclass: <class_name>

                Now an object referring class  here is like
                <class_name> x = new ();

                The new keyword is the built in command that instantiates an object of the class and allocates a memory block for the new object x irrespective of whether an object already exists or not. It allows the object created (here “X”) to access the properties of the class and is passed argument less by default.

                Now Myclass x = new ;   // instantiates an object named x. Constructor is called by compiler.
                Myclass x = new( );   //No-argument Constructor called by the user.

                Thus when the user explicitly calls the no-argument constructor the compiler doesn’t pose an issue or error here instead checks the class for any other similar constructor.
                         Here the new constructor is not returning any value however is returning the properties of the class to the object i.e. <class_name> as well as the address where the new object has been created.

                NOTE- If you won’t define a constructor it gets created by the compiler.
                For example: int x = new int( ) in Java. X gets access to the properties of int.
                One can also define his/her own constructor. It won’t override the default as a constructor is not a method. It cannot be overridden.

                An example in Model Sim
                class myclass;
                             task abc();
                            $display("Hello World Class myclass has been incarnated");
                endtask: abc
                endclass: myclass

                module main;
                            myclass my = new(); //my object created
                            initial begin
                               my.abc(); //my gets class properties thus calls abc
                            end
                endmodule

                The Output is : 



                Q.  What if another new command is used with same object name ?

                An object's memory can be deallocated by using the null command.
                my = null;
                In the above example we have used task in the class. Similarly functions can also be used inside class. 

                Classes can have their own variables. These variables are of local scope until declared as static inside the class. Each instance of this class gets a separate variable and storage. 

                An example of multiple objects with same class using class variables and functions
                class myclass;
                  int a,b;
                  
                             function abc();
                            $display("Result is ",a+b);
                endfunction: abc
                endclass: myclass

                module main;
                            myclass my = new();
                            myclass my1 = new;
                            initial begin
                              my.a = 10;
                              my.b = 5;
                              my1.a = 6;
                              my1.b = 8;
                                  my.abc();
                                  my1.abc();
                            end
                endmodule

                Here is the Output:



                Example with task as well as functions

                class myclass;
                  int a,b;
                  
                             function abc();
                            $display("Result of function is ",a+b);
                endfunction: abc
                task def;
                  $display("Result of task is",a-b);
                endtask: def
                endclass: myclass

                module main;
                            myclass my = new();
                            myclass my1 = new;
                            initial begin
                              my.a = 10;
                              my.b = 5;
                              my1.a = 6;
                              my1.b = 8;
                                  my.abc();
                                  my1.def();
                            end
                endmodule

                Here is the Output:



                Multiple Class declaration


                System Verilog supports multiple class declaration too. Each class has their own separate instance which has further separate variables.

                For example
                class myclass;
                  int a,b;
                  
                             function abc();
                            $display("Result of class A is ",a+b);
                endfunction: abc
                endclass: myclass

                class yourclass;
                  int a,b;
                  task def;
                    $display("Result of class B is",a*b);
                  endtask:def
                endclass:yourclass

                module main;
                            myclass my = new();
                            yourclass my1 = new;
                            initial begin
                              my.a = 10;
                              my.b = 5;
                              my1.a = 6;
                              my1.b = 8;
                                  my.abc();
                                  my1.def();
                            end
                endmodule

                We have created two classes named myclass and yourclass. A and b here are the instances of the myclass and your class respectively.

                The Output

                System Verilog Nested Class


                 A class called within a class itself is called the nested class. The class which holds the nested class is the outer class. 

                class Outer;
                  int a,b;
                  
                             function abc();
                            $display("Result of Outer is ",a+b);
                endfunction: abc
                endclass: Outer

                class Inner;
                    task pain;
                      $display ("Result of inner class is",6/2);
                  endtask:pain
                endclass:Inner

                class Outer_2;
                  int a,b;
                  task def;
                    $display("Result of Outer_2 is",a*b);
                  endtask:def
                  Inner ok = new;
                endclass:Outer_2
                module main;
                            Outer my = new();
                            Outer_2 my1 = new;
                            initial begin
                              my.a = 10;
                              my.b = 5;
                              my1.a = 6;
                              my1.b = 8;
                                  my.abc();
                                  my1.def();
                                  my1.ok.pain();
                            end
                endmodule



                The Output is :



                Here class Outer_2 calls the class Inner and then "ok" object is created. Remember a class cannot instantiate a function and call a function i.e. if we place my1.ok.pain() just below the line Inner ok = new then it will throw an error. It is because only the outer module can call class task's and functions of any class including inner class as well. Try this in your code.

                Another example 
                class Outer_inner;
                  task oi;
                  $display("Result of Outer_inner is ",24/2);
                endtask:oi
                endclass: Outer_inner

                class Outer;

                  int a,b;
                  
                             function abc();
                            $display("Result of Outer is ",a+b);
                endfunction: abc
                Outer_inner ox = new();
                endclass: Outer

                class Inner;

                    task pain;
                      $display ("Result of inner class is",6/2);
                  endtask:pain
                endclass:Inner

                class Outer_2;

                  int a,b;
                  task def;
                    $display("Result of Outer_2 is",a*b);
                  endtask:def
                  Inner ok = new;
                endclass:Outer_2
                module main;
                            Outer my = new();
                            Outer_2 my1 = new;
                            initial begin
                              my.a = 10;
                              my.b = 5;
                              my1.a = 6;
                              my1.b = 8;
                                  my.abc();
                                  my.ox.oi();
                                  my1.def();
                                  my1.ok.pain();
                            end

                endmodule

                The Output is:

                Here the class Outer_inner is called inside the class Outer. It is very important to note that Outer_inner has no access to the properties and variables of Outer class.

                Try replacing this $display("Result of Outer_inner is ",24/2);with this $display("Result of Outer_inner is ",a/2);and you will get an error because Outer_inner has no permission to access Outer variables.