Jump to content

What's the matter with $cast()?


Recommended Posts

Hi, all

 

 

     I has an example as follow:

 

 

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

BasePacket   P1 = new;
My_Packet     P2 = new;

 

 

Case one:

initial begin
//P1 = P2;
P1.printA;
P1.printC;
$cast(P2, P1);
P2.printA;
P2.printC;
end

 

...
# BasePacket::A is           1
# BasePacket::C is           2
# ** Error: (vsim-3971) $cast to type 'class work.obc_pkg_sv_unit::My_Packet' from 'class work.obc_pkg_sv_unit::BasePacket' failed in file ../../sv/top/bip4_vtop.sv at line 80.
#    Time: 0 ps  Iteration: 0  Instance: /bip4_vtop
# My_Packet::A is           3
# My_Packet::C is           4
...

 

 

Case Two:
initial begin
P1 = P2;
P1.printA;
P1.printC;
$cast(P2, P1);
P2.printA;
P2.printC;
end

...
# BasePacket::A is           1
# My_Packet::C is           4
# My_Packet::A is           3
# My_Packet::C is           4

...

 

 

Case one, I didn't assign P1 with P2, the simulator reported error information as above;

the type of P1 is not a superclass of the P2 type?

 

Case twon, I assign P1 with P2 at the begbining, the simulator reported normally as above;

 

Why the assignment of P2 with P1 is cast-compatible after assigned P1 with P2? 

How to do the simulator judge the cast-compatible?

 

So I want to know what the assignment of P1 with P2 does?

 

Thank you in advanced.

 

BR

 

QIN

Link to comment
Share on other sites

Hi, Qin

Sorry misleading you, I check the sv spec, I think the meaning of a successfuly casting from super class to sub class is that the super class is actuall a subclass.

So if the super class in your example P1 is actually not the subclass, the $cast will fail.

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

Hope that will be helpful.

Link to comment
Share on other sites

Hi, Zhuang

 

     I modified the source code as you said as follow:

 

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

BasePacket   P1 = new;
My_Packet    P2;

 

 

initial begin
//P1 = P2;
P1.printA;
P1.printC;
$cast(P2, P1);
P2.printA;
P2.printC;
end

 

The simulator also reported fatal error as follow:

 

 

# BasePacket::A is           1
# BasePacket::C is           2
# ** Error: (vsim-3971) $cast to type 'class work.obc_pkg_sv_unit::My_Packet' from 'class work.obc_pkg_sv_unit::BasePacket' failed in file ../../sv/top/bip4_vtop.sv at line 77.
#    Time: 0 ps  Iteration: 0  Instance: /bip4_vtop
# ** Fatal: (SIGSEGV) Bad handle or reference.
#    Time: 0 ps  Iteration: 0  Process: /bip4_vtop/#INITIAL#73 File: ../../sv/top/bip4_vtop.sv
# Fatal error in Function obc_pkg_sv_unit/My_Packet::printA at ../../sv/top/bip4_vtop.sv line 20

 

 

Could you like to explain the reason?

 

Thank you in advanced.

 

BR

 

QIN

Link to comment
Share on other sites

Cast cannot allocate for elements that are in my_packet and not in basePacket.

In your example, P2 cannot be casted from P1 because the object is not created as a "my packet".

 

To make it work, try (even though the scenario is a bit different):

 

    My_Packet P2 = new;
    BasePacket P1;

     initial begin
        P1 = P2;
        P1.printA;
        P1.printC;
        $cast(P2, P1);
        P2.printA;
        P2.printC;
    end

 

cf http://www.edaplayground.com/s/934/1124

Link to comment
Share on other sites

Another way to understand it is that $cast lets you assign a base class reference to a derived class reference - but the base class reference must refer to an object of the derived class type (which is what fbochud has done above - in his example P1 does actually refer to an object of type My_Packet).

 

It doesn't make sense to put a BasePacket into My_Packet.

 

With inheritance, I always use "is a" to remind myself what's going on.

 

So a My_Packet IS A BasePacket.

But a BasePacket is *not* a My_Packet.

 

Even better use examples like fruit

 

An Apple is a Fruit

but a Fruit is not an Apple

 

(but a variable of type Fruit can hold a reference to an Apple!)

 

regards

Alan

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...