Can I use an extend class in function with an arguments?

Dear all

I’m trying to understand about inheritance in systemverilog.

class A ; 
    virtual function void disp (); 
      $display(" Non-Virtual from A "); 
    endfunction
    virtual function void vdisp (); 
      $display(" Virtual from A "); 
    endfunction
  endclass 

  class EA extends A ;
     virtual function void disp (); 
      $display(" Non-Virtual from EA "); 
    endfunction
     virtual function void vdisp (); 
      $display(" Virtual from EA "); 
    endfunction
  endclass 
   
module main ; 

  function void disp( EA a);
    a.disp();
    a.vdisp();
  endfunction

  	A my_a; 
	EA my_ea;
  
  
  initial 
  begin 
    my_a = new(); 
    my_ea = new(); 
   
 	disp(my_a); 
    disp(my_ea); 
     
  end 
endmodule

To get properties from base class, I implemented with EA argument as the below,

function void disp( EA a);
    a.disp();
    a.vdisp();
  endfunction

but I’ve got found some error when I run this case.

Error-[ICTTFC] Incompatible complex type usage
testbench.sv, 35
Incompatible complex type usage in task or function call.
The following expression is incompatible with the formal parameter of the
function. The type of the actual is ‘class $unit::A’, while the type of the
formal is ‘class $unit::EA’. Expression: my_a
Source info: disp(my_a)

1 error
CPU time: .080 seconds to compile
Exit code expected: 0, received: 1
Done

How can I use EA argument and what am I supposed to resolve this problem?

In reply to verified:

No, basically, you can’t pass a parent class to an argument which is child class type.
To solve this error, you can create function with parent class argument:


  function void disp( A a);
    a.disp();
    a.vdisp();
  endfunction

  // Call it
  disp(my_a); 
  disp(my_ea); 

In reply to chris_le:

Thanks @chris_le,
But I’ve got some unexpected output from the code as the below,


 Non-Virtual from A 
 Virtual from A 
 Non-Virtual from A 
 Virtual from EA 

I thought that it should be like


 Non-Virtual from A 
 Virtual from A 
 Non-Virtual from EA 
 Virtual from EA 

So, Would you please explain why do I get this result? and how to resolve this problem?

In reply to verified:

Are you sure you’re running the same code in your post?


class A ; 
  virtual function void disp (); 
    $display(" Non-Virtual from A "); 
  endfunction
  virtual function void vdisp (); 
    $display(" Virtual from A "); 
  endfunction
endclass 

class EA extends A ;
  virtual function void disp (); 
    $display(" Non-Virtual from EA "); 
  endfunction
  virtual function void vdisp (); 
    $display(" Virtual from EA "); 
  endfunction
endclass 

module main ; 
  function void disp( A a);
    a.disp();
    a.vdisp();
  endfunction

  A my_a; 
  EA my_ea;
  initial 
    begin 
      my_a = new(); 
      my_ea = new(); 

      disp(my_a); 
      disp(my_ea); 

    end 
endmodule

With the code above, result should be:


Non-Virtual from A 
 Virtual from A 
 Non-Virtual from EA 
 Virtual from EA 

It’s how polymorphism work in SystemVerilog. You declare parent’s functions with virtual, then when you pass child object to parent argument of disp, these virtual functions in parent will be completely overridden by child’s functions.

If you don’t want parent’s functions to be overridden, remove virtual keyword.

In reply to chris_le:

Hi,
The original code is like this.

class A ; 
   function void disp (); 
    $display(" Non-Virtual from A "); 
  endfunction
  virtual function void vdisp (); 
    $display(" Virtual from A "); 
  endfunction
endclass 
 
class EA extends A ;
   function void disp (); 
    $display(" Non-Virtual from EA "); 
  endfunction
  virtual function void vdisp (); 
    $display(" Virtual from EA "); 
  endfunction
endclass 
 
module main ; 
  function void disp( A a);
    a.disp();
    a.vdisp();
  endfunction
 
  A my_a; 
  EA my_ea;
  initial 
    begin 
      my_a = new(); 
      my_ea = new(); 
 
      disp(my_a); 
      disp(my_ea); 
 
    end 
endmodule

Would you let me know why do we have to have virtual to all functions?
Actually, the original example isn’t assigned virtual in non-virtual function as you can see the above code.

So I’ve got the below results,

Non-Virtual from A
Virtual from A
Non-Virtual from A
Virtual from EA

I think this example is how vitual work in Systemverilog. But I didn’t get it, do we need vitual keyword for all function?

In reply to verified:

No, we don’t have to have virtual keyword for all functions. You only need virtual functions when you want to use polymorphism (override the by child).

You result is correct because disp() function in A class is declared without virtual. Then it won’t be overridden when you call disp(my_ea).

More about polymorphism, you can search in other threads in this forum or Internet.