UVM基础学习1——创建与覆盖

一、object的创建方式

分析下面一段代码:

class object_create extends top;
    trans t1, t2, t3, t4;
    `uvm_component_utils(object_create)
    function new(string name = "object_create", uvm_component parent = null);
      super.new(name, parent);
    endfunction    
    function void build_phase(uvm_phase phase);
      uvm_factory f = uvm_factory::get(); // get singleton factory
      super.build_phase(phase);
      t1 = new("t1"); // direct construction
      t2 = trans::type_id::create("t2", this); // common method
      void'($cast(t3,f.create_object_by_type(trans::get_type(), get_full_name(), "t3"))); // factory method
      void'($cast(t4,create_object("trans", "t4"))); // pre-defined method inside component
    endfunction
  endclass

这段代码分别用四种方法创建了对象
第一种:new函数不用多说;
第二种:void'($cast(t3, f.create_object_by_type(trans::get_type(), get_full_name(), "t3")));
这行代码展示了如何使用 UVM 工厂的 create_object_by_type 方法来创建一个类型为 trans 的对象,并将其赋值给变量 t3。
重点关心下列函数:

  • 1、create_object_by_type 方法。这个方法需要三个参数: 第一个参数为什么不能直接用trans?

答:因为create_object_by_type 方法的第一个参数需要是类型引用而不是具体的类型实例或类名,这是因为 UVM 工厂使用类型引用来动态创建对象实例。在 SystemVerilog 中,类型引用是通过调用类的 get_type 方法获得的,它返回一个类型标识符(type handle),这个标识符可以用来唯一地标识一个类。
如果直接使用 trans(即 trans::get_type() 的简写),虽然看起来是指定了一个类型,但实际上在编译时,它会被解析为该类型的默认构造函数的引用,而不是类型本身。这会导致 create_object_by_type 方法无法正确地识别要创建的对象类型。

  • 2、那为什么要用get_full_name()?

答:get_full_name() 被用作 create_object_by_type 方法的第二个参数。get_full_name() 方法返回的是当前组件的全名,也就是它在 UVM 组件层次结构中的完整路径名。这个全名是组件的唯一标识符,包含了从顶层组件一直到当前组件的所有组件的实例名,它们之间用点(.)分隔。
例如,如果你有一个组件层次结构如下:

top.env.main_agent.sub_agent1.sub_sub_agent1

在这个结构中,如果 sub_sub_agent1 组件调用了 get_full_name(),它将返回 “top.env.main_agent.sub_agent1.sub_sub_agent1”。
而在代码中,get_full_name() 被用作 create_object_by_type 方法的第二个参数,它将作为新创建的 trans 类型对象的名称的一部分。如果 object_create 的全名是 “top.env.object_create”,那么 t3 的完整名称将是 “top.env.object_create.t3”。这样,t3 就被明确地关联到了 object_create 组件,并且在整个测试环境中具有唯一性。

  • 3、为什么要用cast和void

答:在 UVM 中,使用 $cast 是为了执行对象的类型转换。在 SystemVerilog 和 UVM 的类型系统中,对象可以是多态的,这意味着同一个接口可以有多个实现。当你通过 UVM 工厂创建一个对象时,返回的是一个 uvm_object 类型的句柄,这是因为 UVM 工厂的 create_object_by_type 方法返回类型是 uvm_object。
但是,你通常需要将这个对象转换为特定的派生类型,以便能够访问该派生类型特有的接口和属性。这就是 $cast 函数的用途所在。

以下是 cast 函数的一些关键点:
类型安全 cast 函数提供了一种类型安全的方式来转换对象。如果转换不成功(即对象不是目标类型的实例),$cast 将返回 0,并且不会进行转换。
错误检查:由于 $cast 在转换失败时会返回 0,你可以使用它来进行错误检查,确保对象是预期的类型。
在示例代码中:

void'($cast(t3, f.create_object_by_type(trans::get_type(), get_full_name(), "t3")));

这里 create_object_by_type(…) 调用创建了一个 trans 类型的对象,并返回了一个 uvm_object 类型的句柄。然后,$cast 尝试将这个 uvm_object 类型的句柄转换为 trans 类型。如果转换成功,t3 将包含这个新创建的 trans 对象的句柄,允许后续代码使用 trans 类型特有的接口。如果转换失败,t3 将保持未初始化状态,你可能需要根据你的设计来处理这种情况。

使用 void’(…) 是为了抑制对 $cast 返回值的未使用警告,因为在这种情况下,我们只关心转换后的 t3 变量是否成功指向了正确的类型。

二、component 的创建方式

分析下面代码:(用kimi分析)

class unit extends uvm_component
    `uvm_component_utils(unit)
    function new(string name = "unit",uvm_component parent = null);
        super.new(name,parent);
        `uvm_info("CREATE",$sformatf("unit type [%s] created",name),UVM_LOW);
    endfunction
endclass
class component_create extends top;
    unit u1, u2, u3, u4;
    unit u2_1, u3_1, u4_1;
    `uvm_component_utils(component_create)
    function new(string name = "component_create", uvm_component parent = null);
      super.new(name, parent);
    endfunction
    function void build_phase(uvm_phase phase);
      uvm_factory f = uvm_factory::get(); // get singleton factory
      super.build_phase(phase);
      u1 = new("u1"); // direct construction
      u2 = unit::type_id::create("u2", this); // common method
      u2_1 = unit::type_id::create("u2_1", null); // common method
      void'($cast(u3,f.create_component_by_type(unit::get_type(), get_full_name(), "u3", this))); // factory method
      void'($cast(u3_1,f.create_component_by_type(unit::get_type(), get_full_name(), "u3_1", null))); // factory method
      void'($cast(u4,create_component("unit", "u4"))); // pre-defined method inside component
      void'($cast(u4_1,create_component("unit", "u4_1"))); // pre-defined method inside component
    endfunction
  endclass 
这段代码定义了两个UVM组件类:`unit`和`component_create`。下面是对代码的逐行分析:

1. `class unit extends uvm_component`
   定义了一个名为`unit`的新UVM组件类,它继承自`uvm_component`,这是UVM中所有组件的基类。

2. `` `uvm_component_utils(unit)``
   使用`uvm_component_utils`宏为`unit`类自动实现一些基本方法,如工厂创建方法和类型方法。

3. `function new(string name = "unit", uvm_component parent = null);`
   `unit`类的构造函数,接受一个可选的字符串参数`name`和一个可选的`uvm_component`类型的父组件`parent`。

4. `super.new(name, parent);`
   调用基类`uvm_component`的构造函数,并将`name`和`parent`参数传递给它。

5. `` `uvm_info("CREATE",$sformatf("unit type [%s] created",name),UVM_LOW);``
   使用UVM的报告机制(reporting mechanism)在创建`unit`实例时发出一条低优先级(UVM_LOW)的信息。

6. `endfunction`
   构造函数定义结束。

7. `class component_create extends top;`
   定义了一个名为`component_create`的新UVM组件类,它继承自`top`,代表UVM环境中的顶级组件。

8. `unit u1, u2, u3, u4;`
   在`component_create`类中声明了四个`unit`类型的成员变量。

9. `unit u2_1, u3_1, u4_1;`
   声明了另外三个`unit`类型的成员变量,它们可能是用于展示不同的创建方法。

10. `` `uvm_component_utils(component_create)``
    为`component_create`类自动实现基本方法。

11. `function new(string name = "component_create", uvm_component parent = null);`
    `component_create`类的构造函数。

12. `super.new(name, parent);`
    调用基类`top`的构造函数。

13. `endfunction`
    构造函数定义结束。

14. `function void build_phase(uvm_phase phase);`
    定义了`build_phase`方法,这是UVM组件生命周期的一部分,用于构建子组件。

15. `uvm_factory f = uvm_factory::get();`
    获取UVM工厂的单例实例。

16. `super.build_phase(phase);`
    调用基类`top`的`build_phase`方法。

17. `u1 = new("u1");`
    使用直接构造方法创建`u1`。

18. `u2 = unit::type_id::create("u2", this);`
    使用`unit`的类型ID和`this`(当前`component_create`实例)创建`u2`。

19. `u2_1 = unit::type_id::create("u2_1", null);`
    使用`unit`的类型ID和`null`作为父组件创建`u2_1`。这表明`u2_1`是一个独立的组件,没有父组件。

20. `void'($cast(u3, f.create_component_by_type(unit::get_type(), get_full_name(), "u3", this));`
    使用UVM工厂的`create_component_by_type`方法和`this`创建`u3`。

21. `void'($cast(u3_1, f.create_component_by_type(unit::get_type(), get_full_name(), "u3_1", null));`
    使用UVM工厂的`create_component_by_type`方法和`null`创建`u3_1`,这可能意味着`u3_1`也是独立的组件。

22. `void'($cast(u4, create_component("unit", "u4")));`
    使用`create_component`方法和`this`创建`u4`。

23. `void'($cast(u4_1, create_component("unit", "u4_1")));`
    使用`create_component`方法和`null`创建`u4_1`。

24. `endfunction`
    `build_phase`方法定义结束。

总结来说,这段代码展示了如何在UVM环境中使用不同的方法创建组件实例。它包括直接构造、使用类型ID创建以及使用UVM工厂方法创建。此外,代码还展示了如何创建具有和没有父组件的实例。

主要是想思考下this和null的区别(同样是kimi分析)

在UVM中,组件(components)可以有父组件(parent),也可以没有父组件。组件的父子关系在UVM的组件层次结构中非常重要,因为它影响组件的配置、通信和生命周期管理。以下是有父组件和没有父组件情况下的详细说明:

### 有父组件的情况

当组件实例被创建时,如果提供了父组件的引用,这个实例就会成为其父组件的子组件。这在UVM中是通过在创建组件时传递`this`或父组件的引用来实现的。

- **组件通信**:子组件可以通过父组件访问UVM的报告机制(reporting mechanism),以及使用父组件的配置数据库。
- **配置和覆盖**:子组件可以继承父组件的配置,也可以覆盖它。
- **生命周期管理**:父组件通常负责其子组件的创建和销毁。

在你提供的代码示例中,以下行展示了有父组件的情况:

```verilog
u2 = unit::type_id::create("u2", this); // 有父组件,this是component_create的实例
void'($cast(u3, f.create_component_by_type(unit::get_type(), get_full_name(), "u3", this))); // 有父组件
void'($cast(u4, create_component("unit", "u4"))); // 有父组件

在这些例子中,this代表component_create类的当前实例,作为父组件传递给u2u3u4的创建方法。

没有父组件的情况

当组件实例被创建时,如果没有提供父组件的引用,或者显式地传递了null,这个实例就没有父组件。这样的组件通常被称为顶级组件(top-level components)。

  • 独立性:没有父组件的组件是独立的,它们不依赖于任何其他组件的配置或生命周期管理。
  • 配置:它们需要自己的配置,不能从父组件继承。
  • 生命周期:它们需要自己管理自己的生命周期,比如创建和销毁。

在你提供的代码示例中,以下行展示了没有父组件的情况:

u2_1 = unit::type_id::create("u2_1", null); // 没有父组件,显式传递null
void'($cast(u3_1, f.create_component_by_type(unit::get_type(), get_full_name(), "u3_1", null))); // 没有父组件
void'($cast(u4_1, create_component("unit", "u4_1"))); // 这里虽然传递了null,但create_component方法的行为可能不同

在这些例子中,null被传递给u2_1u3_1的创建方法,表示它们没有父组件。对于u4_1,虽然也传递了null,但create_component方法的行为可能与create_component_by_type不同,因为它是UVM组件类的一个内置方法,可能有不同的处理逻辑。

总结来说,组件是否有父组件决定了它们如何与UVM环境交互,以及它们如何接收配置和被管理。在设计UVM环境时,合理地选择组件的父子关系是非常重要的。

三、覆盖

分析下面这段代码

class object_override extends object_create;
    `uvm_component_utils(object_override)
    function new(string name = "object_override", uvm_component parent = null);
      super.new(name, parent);
    endfunction
    function void build_phase(uvm_phase phase);
      set_type_override_by_type(trans::get_type(), bad_trans::get_type());
      super.build_phase(phase);
    endfunction
  endclass

这段代码主要想的是为什么set_type_override_by_type可以直接用,而不是用factory.set_type_override_by_type()(总是关注在一些奇奇怪怪的点)
kimi分析如下:

在UVM中,`set_type_override_by_type`这个操作通常与工厂(factory)相关,因为它涉及到组件类型的创建和管理。然而,在这段代码中,并没有使用`factory.set_type_override_by_type`的调用形式,而是直接使用了`set_type_override_by_type`。这种用法是合法的,原因如下:

1. **组件内建方法**:在UVM组件类中,`set_type_override_by_type`可以作为组件的一个内建方法直接调用,而不需要显式地引用工厂对象。这是因为UVM组件类内部已经与工厂交互,允许直接设置类型覆盖。

2. **隐式工厂引用**:当在UVM组件的上下文中调用`set_type_override_by_type`时,UVM框架会隐式地使用当前的工厂实例来执行这个操作。因此,即使代码中没有显示地引用`factory`对象,实际上也是在与工厂进行交互。

3. **简化API**:UVM提供了简化的API,允许在组件类中直接使用一些工厂相关的操作,而不需要每次都显式地获取工厂实例。这样做可以减少代码的冗余,并使代码更加清晰易读。

4. **UVM组件的特权**:作为UVM组件的一部分,`set_type_override_by_type`方法可以利用组件的上下文信息,例如当前的组件实例和工厂设置,而不需要额外的参数。

因此,`set_type_override_by_type(trans::get_type(), bad_trans::get_type());`这种用法是UVM设计的一部分,旨在简化组件的创建和管理。在UVM的组件类中,你可以直接调用这个方法来设置类型覆盖,而不需要显式地使用`factory`对象。这是UVM提供的一种便利,使得组件的配置和管理更加直观和高效。

这里需要注意,set_type_override_by_type可以直接在 UVM 组件类中调用,不需要通过 UVM 工厂对象。而create_object_by_type通常通过 UVM 工厂对象调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/781582.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3+Vue3开发园区管理系统

介绍 在当今快速发展的城市化进程中,高效、智能的园区管理成为了提升居民生活品质、优化企业运营环境的关键。为此,我们精心打造了全方位、一体化的园区综合管理系统,该系统深度融合了园区管理、楼栋管理、楼层管理、房间管理以及车位管理等…

微信小程序消息通知(一次订阅)

在微信公众平台配置通知模版 通过wx.login获取code发送给后端 let that this // 登陆codewx.login({success: function (res) {if (res.code) {// 发送code到后端换取openid和session_keythat.setData({openCode: res.code})console.log(that.data.openCode, openCode);// 调…

【SpringBoot】SpringBoot内置Servlet容器源码分析-Tomcat

自动装配加载 ServletWebServerFactoryAutoConfiguration 在自动装配的时候,会加载spring.factories,并且添加到IOC容器中。这里包含web自动配置类ServletWebServerFactoryAutoConfiguration ,其中本类中注入三个bean,分别是Embed…

【数据结构与算法】插入排序

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ​

Ollama报错:Error: llama runner process has terminated: exit status 0xc0000409

0,背景 今天听说谷歌家的Gemma2性能很好,于是在Ollama上下载到本地测试一下 ollama run gemma2 结果终端里报错 Error: llama runner process has terminated: exit status 0xc0000409 1,原因 原因很简单,新的模型&#xff…

vue项目实现堆叠卡片拖动切换效果

实际效果 实现流程 1. 实现卡片位置堆叠 将父元素的 position 设置成relative ,卡片的position 设置成 absolute 即可。 2. 消除图片的移动 如果卡片上有图片,默认拖动的时候就会导致像上图一样变成了选中图片移动,从而没法触发拖动事件。消…

Canal架构以及使用规范

Canal架构以及使用规范 一、Canal的作用 相关文档:GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 MySQL主备复制原理 MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可…

上网监控软件有哪些?3款实力出众的上网监控软件

为什么需要上网监控软件? 据说,99%的员工上班都会摸鱼,1%的员工上班会窃取公司信息。 所以,因此,监控员工的上网行为是很有必要滴。 总结下来,上网监控软件的作用是: 1.提高生产力&#xff1…

Vben:表格的表头和表格的内容对不齐,以及解决方法

文章目录 一、问题描述二、解决方法 一、问题描述 基于Vue-Vbne-admin框架进行前端开发的时候,调用表格useTable函数实现表格之后,发现表格的表头和表格的内容对不齐。如下图所示。针对这种情况,本文记录了解决方法。 调用的模块如下&#x…

1958.力扣每日一题7/7 Java(100%解)

博客主页:音符犹如代码系列专栏:算法练习关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 目录 思路 解题方法 时间复杂度 空间复杂度 Code 思路 首先将指定位…

浏览器插件利器-allWebPluginV2.0.0.14-stable版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品,致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX插件直接嵌入浏览器,实现插件加载、界面显示、接口调用、事件回调等。支持谷歌、火狐等浏…

并查集(还有反集也在)

一.定义 定义: 并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。 主要构成: 并查集…

2-27 基于matlab的一种混凝土骨料三维随机投放模型

基于matlab的一种混凝土骨料三维随机投放模型,为混凝土细观力学研究提供一种快捷的三维建模源代码。可设置骨料数量,边界距离、骨料大小等参数。程序已调通,可直接运行。 2-27 matlab 混凝土骨料三维随机投放模型 - 小红书 (xiaohongshu.com)…

Redis 7.x 系列【16】持久化机制之 AOF

有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 执行原理2.1 Redis 6.x2.1.1 直接写2.1.2 重写 2.2 Redis 7.x2.2.1 直接写2…

PTA甲级1005:Spell It Right

错误代码&#xff1a; #include<iostream> #include<vector> #include<unordered_map> using namespace std;int main() {unordered_map<int, string> map {{0, "zero"}, {1, "one"}, {2, "two"}, {3, "three&qu…

线程安全的原因及解决方法

什么是线程安全问题 线程安全问题指的是在多线程编程环境中&#xff0c;由于多个线程共享数据或资源&#xff0c;并且这些线程对共享数据或资源的访问和操作没有正确地同步&#xff0c;导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现&#xff0c;通常是…

【大数据综合试验区1008】揭秘企业数字化转型:大数据试验区政策数据集大公开!

今天给大家分享的是国内顶级期刊中国工业经济2023年发布的最新期刊《政策赋能、数字生态与企业数字化转型——基于国家大数据综合试验区的准自然实验》文章中所使用到的数据集——国家大数据综合试验区政策数据集以及工具变量数据&#xff0c;该文章基于2009-2019年中国上市企业…

两个全开源的3D模型素材下载网站源码 3D图纸模型素材 三维图形素材会员下载站源码

今天推荐两个全开源的3D模型素材下载网站源码 3D图纸模型素材 三维图形素材会员下载站源码&#xff0c;这两个源码完整&#xff0c;都是基于thinkphp内核开发的&#xff0c;框架稳定&#xff0c;带数据库&#xff0c;源码文件&#xff0c;可以直接部署使用。 第一个&#xff1a…

【数据结构与算法】快速排序挖坑法

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​