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

简介: 【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的,那也一样会报编译问题:



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


相关文章
|
C语言
《C语言及程序设计》程序阅读——递归函数
返回:贺老师课程教学链接 阅读下面的程序,写出运行结果,并和上机运行的结果对照 (1) #include <stdio.h> long fun(int n) { long s; if(n==1||n==2) s=2; else s=n+fun(n-1); return s; } int main
1065 0
|
8月前
|
存储 算法 C语言
芯片验证 | SystemVerilog使用简介
芯片验证 | SystemVerilog使用简介
189 0
|
安全 C++ C语言
static_cast与dynamic_cast的联系与区别
1.static_cast在编译时期强制转换,dynamic_cast在运行时期转换(较安全)       2.static_cast是c语言的强制转换代替品;dynamic_cast会运行时检查该转换是否类型安全,只在多态类型时合法,即该类至少具有一个虚拟方法。
7329 0
|
机器学习/深度学习 传感器 算法
【RBF回归预测】基于径向基神经网络时间序列预测附Matlab完整源码
【RBF回归预测】基于径向基神经网络时间序列预测附Matlab完整源码
|
开发工具 内存技术
zynq程序固化补充篇: 不切换启动模式强制烧写
使用SDK2018.2第一次进行烧写 Flash,在qspi模式下会报错,只有切换至jtag模式下才可以进行烧录,后续的再次烧录不会出现类似问题。但是调试的时候必须切回jtag模式(将BOOT MODE 5拉低才可以调试)
2422 1
zynq程序固化补充篇: 不切换启动模式强制烧写
|
芯片 索引 内存技术
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
|
C语言
UEFI系统组成
UEFI系统组成
164 0
|
监控 关系型数据库 数据库
PostgreSQL pgmetrics - 多版本、健康监控指标采集、报告
标签 PostgreSQL , pgmetrics , check_postgres 背景 pgmetrics,GO写的一款PostgreSQL 多版本、健康监控指标采集、报告开源软件。 https://github.com/rapidloop/pgmetrics 结合pgdash,可以实现被监控PG实例的可视化,指标值变更告警等。
1308 0
|
SQL 关系型数据库 MySQL

热门文章

最新文章