Friday 8 May 2015

Down Cast in SystemVerilog and virtual concept in SystemVerilog

// Command to run in questa
// 1. vlib work
// 2. vlog -sv top.sv
// 3. vsim top -c
// 4. run -all (in vsim prompt)

class base;

  int a = 5;
endclass

class extend extends base;
  int b = 1;
endclass

module top;
  initial begin
    base     m_base;
    extend  m_extend;
    
    m_extend = new();
    m_base    = new();
    $cast(m_extend, m_base);
    $display(m_extend.a);
  end
endmodule

//Error: (vsim-3971) $cast to type 'class work.top1_sv_unit::extend' from 'class work.top1_sv_unit::base' failed in file top.sv

Meaning of a successfully casting from super-class(parent class) to sub-class(child class) is that the super-class is actually a sub-class.

class BasePacket;
  int A = 1;
  int C = 2;

  function void printA;
    $display("BasePacket::A is %d", A);
  endfunction : printA

  virtual function void printC;
    $display("BasePacket::C is %d", C);
  endfunction : printC
endclass : BasePacket

class My_Packet extends BasePacket;
  int A = 3;
  int C = 4;

  function void printA;
    $display("My_Packet::A is %d", A);
  endfunction: printA

  virtual function void printC;
    $display("My_Packet::C is %d", C);
  endfunction : printC
endclass : My_Packet

module top;
  initial begin
My_Packet EXT = new;
BasePacket BASE;

BASE = EXT;
BASE.printA;
BASE.printC;
$cast(EXT, BASE);
EXT.printA;
EXT.printC;
end
endmodule : top

//Output:
// BasePacket::A is           1
// My_Packet::C is           4
// My_Packet::A is           3
// My_Packet::C is           4

Here super-class in this example (BASE) is actually the sub-class (EXT), so the $cast is passed.

Here for first call (using BASE handle) of printA and printC, super-class (BASE) is acutally sub-class (EXT) and function printC is declared as virtual in super-class (BASE), so it will execute printC function of sub-class (EXT).
But, function printA is not declared as virtual in super-class (BASE), so it will execute printA function of super-class (BASE), in-spite of it is actually having memory of EXT class, because handle is of super-class.

One usual scenario to use the $cast is to pass some sub-class data into other class, and the developer of the receptor class even don't know if the incoming class is what kind of sub-class, so usually he will in the receptor class use a super(parent)-class to get the incoming data and then use $cast to check/transfer the data into certain sub-class.

No comments:

Post a Comment