Why the task body() inside sequence is of type virtual?

Hi All,
Why specifically the task body() inside the sequence is defined to be of type virtual?? any specific reason?? And even in the examples given inside the ovm examples, they had defined the body to be of type virtual!!! Got tweaked in mind suddenly and confused :confused:

Thanks,
Desperado → :rolleyes:

Useing it, you can override this function of body in your style.

Hi All,
Why specifically the task body() inside the sequence is defined to be of type virtual?? any specific reason?? And even in the examples given inside the ovm examples, they had defined the body to be of type virtual!!! Got tweaked in mind suddenly and confused :confused:
Thanks,
Desperado → :rolleyes:

If the sequence is overridden (using factory) then we would like the new body to take effect. Is that not the reason. On the other hand, I am wondering why pre_body and post_body aren’t virtual if thats what you meant …

Hi Angelo,

ofcourse the pre-body and post-body are of type virtual in the ovm_sequence_base.svh base class.
But just the doubt was why the body is declared to be of type virtual in the sequence in the examples as well, so the reason is while if you want to override using any of the methods and if the later want to take the effect over the formal, so for this case you need it to be of type virtual !! Is what I understood, am i correct ?? If not correct me.

Thanks,
Desperado → Silent Killers all around

Hi Angelo,
ofcourse the pre-body and post-body are of type virtual in the ovm_sequence_base.svh base class.
But just the doubt was why the body is declared to be of type virtual in the sequence in the examples as well, so the reason is while if you want to override using any of the methods and if the later want to take the effect over the formal, so for this case you need it to be of type virtual !! Is what I understood, am i correct ?? If not correct me.
Thanks,
Desperado → Silent Killers all around

Hi Desperado,

Correct.

Virtual methods are an important part of late binding.
I guess your question has 2 parts:

  1. once a method is declared virtual in the base class, its not necessary to again declare it virtual in the derived class (I hope I am right here)
  2. If a method is not declared as virtual, the compiler will invoke the method call simply based on the object type. So if you were to override the object later it would not have any effect since you never specified your intention of late binding (you did not use virtual). So the compiler did a static binding and it can only do that using the object type which is deterministic at compile time.

Sorry for the long reply but I was not sure of the question.

I would also recommend you to see some C++ write ups related to late binding.
That would help a lot in understanding the polymorphism …

Thank you …

Hello,

Hi Desperado,
Virtual methods are an important part of late binding.
I guess your question has 2 parts:

  1. once a method is declared virtual in the base class, its not necessary to again declare it virtual in the derived class (I hope I am right here)

Yes, that’s how SystemVerilog works - the virtual is “sticky”. We demonstrate that during our advanced SystemVerilog sessions/labs to customers.

Regards
Srini
www.cvcblr.com/blog

Hi All,

Fine as the the concept of virtual, if defined in the base class as virtual there is no need to specify that same function as virtual in the extended class!!!

BUT

In the ovm_sequence_base, the task “body” is declared to be of type virtual, then why are they again defining it to be of type virtual when they create the custom sequence extending the base sequence in all the example given along with the ovm package. Is there any specific need for the same??? If so kindly please let me know.

Thanks,
Desperado → Just escaped from the accident

Hi All,
Fine as the the concept of virtual, if defined in the base class as virtual there is no need to specify that same function as virtual in the extended class!!!
BUT
In the ovm_sequence_base, the task “body” is declared to be of type virtual, then why are they again defining it to be of type virtual when they create the custom sequence extending the base sequence in all the example given along with the ovm package. Is there any specific need for the same??? If so kindly please let me know.
Thanks,
Desperado → Just escaped from the accident

From: http://www.learncpp.com/cpp-tutorial/122-virtual-functions/

Only the most base class function needs to be tagged as virtual for all of the derived functions to work virtually. However, having the keyword virtual on the derived functions does not hurt, and it serves as a useful reminder that the function is a virtual function rather than a normal one. Consequently, it

In reply to sri.cvcblr:

Hello,
Hi Desperado,
Virtual methods are an important part of late binding.
I guess your question has 2 parts:

  1. once a method is declared virtual in the base class, its not necessary to again declare it virtual in the derived class (I hope I am right here)
    Yes, that’s how SystemVerilog works - the virtual is “sticky”. We demonstrate that during our advanced SystemVerilog sessions/labs to customers.
    Regards
    Srini
    www.cvcblr.com/blog

Could you please let me know more about “sticky” why the virtual is sticky?

In reply to UVM_LOVE:

The reason has to do the way virtual methods get called via a lookup table.

class_variable.method_called(arguments)

The compiler looks at the type of ‘class_variable’ and sees how ‘method_called’ is defined. If a virtual method, it then looks at the object type stored in class_variable and uses that to check which method gets called. The problem with a later non-virtual method is that class_variable only know about the method prototype for that point in the inheritance tree, so it assumes all later derived methods are virtual.

Also, to answer the original question better, body() has to be virtual so it can be called from the uvm_sequence base class variable. Thats why build_phase etc. are all virtual too.

In reply to dave_59:

Hi Dave,

“body() has to be virtual so it can be called from the uvm_sequence base class variable.”

Say if we have a extended sequence that extends from the base sequence. And in case we are going to use a object of type (extended class sequence) then in this case it would automatically call the task body() defined in the extended sequence right and, for this you dont need to have the base sequence as virtual. This will be just pure inheritance right.

But yes if you want to use the base sequence handle which is pointing to extended sequence class object then in this case you need the base class as a virtual method so that the appropriate call is made. Hope my understanding is correct.

Also now if you have another ext2 sequence which extends from this extended sequence and, say this ext2 sequence is pointing to the extended sequence object. Now if you want to call the method defined in the ext2 sequence then the extended class sequence method needs to be virtual correct.

Also can you please elaborate on this if possible with a quick example. Thanks

“The problem with a later non-virtual method is that class_variable only know about the method prototype for that point in the inheritance tree, so it assumes all later derived methods are virtual”

In reply to sriram.seshagiri:

Hi Dave,

I am kind of having the same confusion still.

In the uvm_sequence_base, the task “body” is declared to be of type virtual, then why are they again defining it to be of type virtual when they create the custom sequence extending the base sequence in all the example given along with the ovm package. Is there any specific need for the same??? If so kindly please let me know.

since the base sequence class is already virtual what s the need of the custom sequence also having the virtual method for task body ?

As a quick example: Here it is not reqd for class D to be virtual

class C;
   virtual function void display();
    $display("C!");    
  endfunction : display
endclass : C
 
class D extends C;
   function void display();
    $display("D!");      
  endfunction : display
endclass : D

class E extends D;
  int a;
   function void display();
     $display("E!");      
  endfunction : display
endclass : E


initial begin
D D0 = new();
      E E0 = new();
D0 = E0;
      D0.display();
end

In reply to sriram.seshagiri:

Once virtual, always virtual.

The rule is once a method is marked virtual, it is always virtual in all derived classes. The virtual keyword becomes optional. A very confusing feature.

In reply to dave_59:

Hi Dave,

Thanks. That means to say in UVM say you have

Class my_uvm_agent extends uvm_agent;

virtual function build phase (); //**This virtual function is Optional here right since the Base class uvm_agent already is Virtual by default. Please correct me if wrong.
**
endfunction

endclass