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



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


目录
打赏
0
0
0
0
2
分享
相关文章
MQTT常见问题之mqtt 报 MqttException:客户机未连接如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
Docker swarm实现基于Consul和Haproxy的RabbitMQ高可用集群
基于Consul服务发现和Haproxy实现的RabbitMQ高可用的负载均衡集群
仅3步!即刻拥有 QwQ-32B,性能比肩全球最强开源模型
本文介绍如何将QwQ-32B开源模型部署到阿里云函数计算FC,并通过云原生应用开发平台CAP实现Ollama和Open WebUI两个FC函数的部署。Ollama负责托管QwQ-32B-GGUF模型,Open WebUI提供用户交互界面。借助CAP平台,用户可快速完成模型部署,无需关注底层资源管理与运维问题,专注于应用创新与开发。CAP提供免运维、弹性伸缩及高可用性的高效开发环境,并采用按量付费模式降低资源成本。方案使用华北2(北京)地域,默认配置部署,预计耗时10~12分钟。体验后建议清理资源以避免额外费用。
仅3步!即刻拥有 QwQ-32B,性能比肩全球最强开源模型
Android中弹框如何设计成全屏的
本文介绍在Android中实现全屏对话框的方法,包括使用`Dialog`和`DialogFragment`两种方式。通过设置对话框无标题、调整布局参数及使用透明背景实现全屏效果。适用于希望提升应用交互体验的开发者。
221 0
芯片验证 | SystemVerilog使用简介
芯片验证 | SystemVerilog使用简介
321 0
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
使用 `defer` 属性异步加载 JavaScript
【10月更文挑战第24天】使用 `defer` 属性异步加载 JavaScript 是一种有效的提高页面性能和用户体验的方法。通过合理设置 `defer` 属性,可以在不影响页面渲染的情况下异步加载脚本,并确保脚本的执行顺序。在实际应用中,需要根据具体情况选择合适的加载方式,并注意处理可能出现的问题,以确保页面能够正常加载和执行。
|
9月前
|
LLM-03 大模型 15分钟 FineTuning 微调 GPT2 模型 finetuning GPT微调实战 仅需6GB显存 单卡微调 数据 10MB数据集微调
LLM-03 大模型 15分钟 FineTuning 微调 GPT2 模型 finetuning GPT微调实战 仅需6GB显存 单卡微调 数据 10MB数据集微调
230 0
SEO外链自动发布外链工具网站源码
这套程序相当简洁,只有几个主程序和调用文件,无需数据库,无需安装,只要将文件上传到PHP环境就可以运行了,对PHP版本也要求较低,建议采用PHP5.6或者以上。
227 0
SEO外链自动发布外链工具网站源码
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等