1
votes

This question might be applicable to all/most Object-oriented programming languages but I am only concerned about the SystemVerilog side. Polymorphism, I thought I understood, until I was talking to a colleague the other day and this came and I realised that I don't know how this can be done. Following are the two classes to consider for the purpose of this discussion -

class four_wheeler;

    virtual function void vehicle_type();
        $display("Four-wheeler");
    endfunction:vehicle_type

    virtual task colour();
        $display("Many colours");
    endtask:colour
endclass:four_wheeler

class jaguar extends four_wheeler;

    function void vehicle_type();
        $display("Jaguar");
    endfunction:vehicle_type

    task colour();
        $display("Black");
    endtask:colour
endclass:jaguar

program sv_prog;

  initial begin
    four_wheeler four_wheeler_h;
    jaguar  jaguar_h;

    four_wheeler_h = new();
    jaguar_h = new();

    four_wheeler_h = jaguar_h;
    four_wheeler_h.vehicle_type();

  end

endprogram: sv_prog

I want to access the vehicle_type() function in the base class four_wheeler using its own object. I can do this by four_wheeler_h.vehicle_type() before the four_wheeler_h = jaguar_h copy. Regular OOP working! But can I do it after the copy of the handle? I can use the super keyword in jaguar class vehicle_type() method:

function void vehicle_type();
    super.vehicle_type();
    $display("Jaguar");
endfunction:vehicle_type

and get the output:

Four-wheeler
Jaguar

But I am more interested in doing this from the program block itself without having to modify the function in the jaguar class. Is there any way I can achieve that? Maybe a use of super from the program block itself.

2
I think you need to describe a real use case for what you are trying to achieve. For your example, why bother making vehicle_type a virtual method? - dave_59
It actually is a hypethetical question to understand the abilities/limitations of the language. - Timothy Grant
There could be a use case where I want to access the base class method and derived class method - both, using only the base class object, in that case I need to make the base class method virtual, but then I lose access to that method if I have to, at some point later, access it. So my question to you too, can I somehow, 'un'pass the derived class handle to base class variable and be able to access the base class method after having accessed the derived class method first (for which I had passed the derived class handle to the base class variable)? - Timothy Grant

2 Answers

2
votes

I afraid that unlike in c++, you are very limited in the ways of doing it (like in java). So, all languages are different.

Similarly to java, SystemVerilog provides you with the keyword 'super' which you can use in class members. You will have to create a specific class member function for access its base(super)-class members in the non-class scope:

class jaguar extends four_wheeler;
   ...

   function super_vehicle_type();
     super.vehicle_type();
  endfunction

endclass:jaguar

now you can use

jaguar_h.super_vehicle_type();

you can also use class scope identifier in the function to access any of the base classes.

   function super_vehicle_type();
     four_wheeler::vehicle_type();
  endfunction

In the above case you can use any of the base classes (instead of the four_wheeler) as a class scope.

2
votes

The simple answer is a no, that's not how virtual methods work. Polymorphism defines it in such away that you are not supposed to be aware that you are dealing with an overridden class object. It's like asking if you've declared a member as local or protected, is there any way to access that member from outside the class. The answer to that is no as well. But... there are ways that you can control access to those member variables and methods if you provide additional accessor methods in the base class.

class base;
  local int base_variable;
  virtual function void do_this;
  endfunction
  function int get_base_variable;
     return base_variable;
  endfunction
  function void base_to_this;
     base::do_this();
  endfunction
endless