关于SystemVerilog向下类型转换

Question: SystemVerilog是否支持向下类型转换(将基类对象转换为派生类对象)? 如果可以,怎么做?

以下downcast示例不起作用:

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

Answer: 是的,你可以downcast。 你的例子是正确的语法,它实际上编译通过。 但是,您收到runtime错误,因为downcast失败。在你的例子中强制转换失败,因为只有基类对象的句柄实际引用了派生类型的对象,才能成功向下转换。 你可以调用$ cast作为一个函数,它将返回一个布尔值,指示downcast是否成功。

下面给出正确的例子:

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
IEEE Std 1800-2012中关于Casting的描述如下:

子类型表达式分配给继承树(超类或表达式类型的祖先)中较高类类型的变量总是合法的。 将父类型的变量直接赋值给它的一个子类类型的变量应该是非法的。 但是,只要父类句柄指向与子类变量兼容的对象,就可以使用$ 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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值