SystemVerilog是否支持向下转型?

时间:2013-12-12 16:12:03

标签: casting system-verilog

SystemVerilog是否支持向下转换(将基础对象转换为派生对象)?如果是这样,怎么样?

以下向下转播示例不起作用:

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

修改并重新运行EDA Playground上的示例:http://www.edaplayground.com/s/4/581

2 个答案:

答案 0 :(得分:9)

是的,你可以垂头丧气。您的示例是正确的语法,它实际上是编译。但是,由于转换失败,您将收到运行时错误。

您示例中的强制转换失败,因为如果基础对象的句柄实际引用派生类型的对象,则只能成功转发。您可以将$cast作为函数调用,它将返回一个布尔值,指示转换是否成功。

以下是一个例子:

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

输出:

# Found a dog!
# woof

请参阅http://www.edaplayground.com/s/474/586

答案 1 :(得分:4)

IEEE Std 1800-2012§8.16“施法”声明:

  

将子类类型的表达式分配给继承树(表达式类型的超类或祖先)中更高类类型的变量始终是合法的。将超类类型的变量直接分配给其子类类型之一的变量是非法的。但是,$cast可用于为超类类型的变量分配超类句柄,前提是超类句柄引用与子类变量赋值兼容的对象。

以下转换失败,因为超类对象不能被读作子类。

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

要正确转换,源句柄的对象必须与目标类型兼容,必须具有可比性:

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

向下转换可以通过继承级别工作。下面的示例演示了一个基类句柄,指向将孙子对象转换为扩展类(孙子对象的父类):

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

以下是一些工作示例:http://www.edaplayground.com/s/6/587