What is Difference between downcasting and upcasting Systemverilog?

Hi Everone ,

 I was googling for Definition of upcasting and down-casting in SV. the search result is making confuse ? Please clear this concept. 

Regards
kbkdec15

In reply to kbkdec15:

Hi kbkdec15,

I hope by this time you must have found the answer for this.

We take the advantage of inheritence and polymorphysm of SV classes here. Upcasting is where we assign the derived class’s handle to base class. The advantage is obvious: reusability.


class base;
  int a = 5;
endclass

class child extends base;
  int b = 6;
endclass

module top;
  initial begin
    base base_h;
    child child_h;
    child_h = new();
    $cast(base_h, child_h); // same as: base_h = child_h;
    $display(child.a); // a is base's property
  end
endmodule

Now downcasting is opposite of the above; assigning the base class handle to child class handle. But this will not work until the base class handle already refers to child class handle. When an array of base class is present, where it is filled with different child class handles, this downcasting comes handy. Check the following code (copied from casting - Does SystemVerilog support downcasting? - Stack Overflow):


class animal;
  function void eat();
  endfunction
endclass

class dog extends animal;
  function void bark();
    $display("woof");
  endfunction
endclass

class cat extends animal;
  function void meow();
    $display("meow");
  endfunction
endclass

module test;

  initial begin
    dog a_dog = new();
    cat a_cat = new();

    animal animals[$];
    animals.push_back(a_dog);
    animals.push_back(a_cat);

    foreach (animals[i]) begin
      dog another_dog;
      animals[i].eat();
      if ($cast(another_dog, animals[i])) begin
        $display("Found a dog!");
        another_dog.bark();
      end
    end

  end
endmodule

Hope that helps.
-mpattaje

In reply to mpattaje:

The casting in the first example is redundant as the child already have the variable a, as it inherits all properties of the base class. So, if the casting wasn’t done, still the access of child_h.a is valid.

Upcasting is basically used with virtual methods, where you want to access base class methods using the variable of the superclass. Below example will clarify the idea:


class BasePacket;
  int A =1;
  int B = 2;
  function void printA;
  $display("BasePacket::A is %d", A);
  endfunction : printA
  virtual function void printB;
  $display("BasePacket::B is %d", B);
  endfunction : printB
  endclass : BasePacket

class My_Packet extends BasePacket;
  int A = 3;
  int B = 4;
  function void printA;
  $display("My_Packet::A is %d", A);
  endfunction: printA
  virtual function void printB;
  $display("My_Packet::B is %d", B);
  endfunction : printB
  endclass : My_Packet

module main;
  BasePacket P1 = new;
My_Packet P2 = new;
initial begin
P1.printA; // displays 'BasePacket::A is 1'
P1.printB; // displays 'BasePacket::B is 2'
$case(P1,P2) // same as P1 = P2..  P1 has a handle to a My_packet object
P1.printA; // displays 'BasePacket::A is 1'
P1.printB; // displays 'My_Packet::B is 4' – latest derived method
P2.printA; // displays 'My_Packet::A is 3'
P2.printB; // displays 'My_Packet::B is 4'
end
endmodule: main

1 Like