Does SystemVerilog support downcasting?

Does SystemVerilog support downcasting (casting a base object to a derived object)? If so, how?

The following example does not work:

class base; int a = 5; endclass class extend extends base; int b = 1; endclass module test; initial begin base m_base; extend m_extend; m_base = new(); m_extend = new(); $cast(m_extend, m_base); $display(m_extend.a); end endmodule 

Change and repeat the example on the EDA Playground: http://www.edaplayground.com/s/4/581

+6
source share
2 answers

Yes, you can lower. Your example is the correct syntax and it really compiles. However, you get a runtime error because the failure is executing.

The cast to your example is unsuccessful because you can only successfully disconnect if the handle to the base object does refer to the object of the derived type. You can call $cast as a function, and it will return a boolean indicating whether success was successful or not.

Here is an example:

 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 

Outputs:

 # Found a dog! # woof 

See http://www.edaplayground.com/s/474/586

+7
source

IEEE Std 1800-2012 & sect; 8.16 "Casting":

It is always the right to assign an expression of a subclass type to a variable of a class type higher in the inheritance tree (superclass or ancestor of the expression type). The direct assignment of a variable of the type of a superclass to a variable for one of its subclass types is unacceptable. However, $cast can be used to assign a superclass descriptor to a variable of a subclass type if the superclass descriptor refers to an object that is an assignment compatible with the subclass variable.

The following actions are not performed because the superclass object is not read as a child class.

 m_base = new(); $cast(m_extend, m_base); // destination type != source object type 

In order to correctly apply the source descriptor object, it must be compatible with the destination type, which must be comparable:

 m_extend = new(); m_base = m_extend; $cast(m_extend, m_base); // destination type == source object type 

Downcasting can work through inheritance levels. The following example demonstrates a base class descriptor that points to a grandson object passed to the extend class (the parent class of the grandchild object):

 class ext_more extends extend; int c; endclass initial begin base m_base; extend m_extend; ext_more m_ext_more; m_ext_more = new(); m_base = m_ext_more; $cast(m_extend, m_base); // legal, casting a subclass object to a parent handle $display(m_extend.a); end 

Here are some working examples: http://www.edaplayground.com/s/6/587

+3
source

All Articles