【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法(5)

前言

之前在几篇博客中提到了下$cast方法的原理和行为:

【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法(4)

【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法(3)

【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法(2)

【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法(1)

今天发现之前的说法还是有疏漏,补充一下;

两个疏漏

第一点:$cast不检查空句柄

之前聊过$cast的本质,就像下面这个图:

 那么问题是,如果$cast(a,b)中的b是一个空句柄,那么$cast是否会告警或者cast失败呢?答案是不会的,这个时候无论是$cast(a,b)还是还是if(!$cast(a,b))都不会报错,比如下面这个测试:

function my_rm::new(string name, uvm_component parent);
    my_transaction tr0;
    uvm_sequence_item tr1;
    super.new(name, parent);
    if(!$cast(tr0, tr1)) 
        `uvm_fatal("my_rm", "hahaha");
endfunction 

跑完的结果:

正因为如此,我们才需要去裹一层宏来处理,比如说这样:

`define prj_cast(to, from) \
    if (from == null) begin\
        `uvm_fatal("prj_cast", "cast NULL");\
    end\
    if(!$cast(to, from)) begin\
        `uvm_fatal("prj_cast", "cast fatal");\
    end\

 同样刚刚的代码就会是这样:

function my_rm::new(string name, uvm_component parent);
    my_transaction tr0;
    uvm_sequence_item tr1;
    super.new(name, parent);
    if(!$cast(tr0, tr1)) 
        `uvm_fatal("my_rm", "hahaha");
    `prj_cast(tr0, tr1);
endfunction 

 第二点:空句柄时无脑cast成功

当from为空句柄时,那么就不要指望cast检查什么行为合理了,这个时候是必然成功的。看刚刚的例子就知道了,tr1是父类句柄,tr0是子类句柄,!cast(tr0, tr1)没能检查出问题。当然了,这种也不算漏洞吧,只要你tr1 new()过就可以报出来了:

function my_rm::new(string name, uvm_component parent);
    my_transaction tr0;
    uvm_sequence_item tr1 = new();
    super.new(name, parent);
    if(!$cast(tr0, tr1)) 
        `uvm_fatal("my_rm", "hahaha");
endfunction

自我纠正 

不知道我是写过还说说过类似这样的话:除了检查是不是左侧句柄最终指向了本身或其子类的空间之外,用$cast和用=没有区别。如果我说过的话,那就当我没说过......

$cast不仅是检查,而且符合标准是会顺利让你通过,而=是无脑不让你过,比如说这个代码:

function my_rm::new(string name, uvm_component parent);
    my_transaction tr0;
    uvm_sequence_item tr1 = my_transaction::new();
    super.new(name, parent);
    if(!$cast(tr0, tr1)) 
        `uvm_fatal("my_rm", "hahaha");
    //tr0 = tr1;
endfunction

可以说完全没有任何问题:

可是如果加上一句:

function my_rm::new(string name, uvm_component parent);
    my_transaction tr0;
    uvm_sequence_item tr1 = my_transaction::new();
    super.new(name, parent);
    if(!$cast(tr0, tr1)) 
        `uvm_fatal("my_rm", "hahaha");
    tr0 = tr1;
endfunction 

哪怕tr0是完全可以指向tr1的,那也一样会报编译问题:

只能说=的检查过于苛刻和古板了。 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼德兰的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值