UVM入门实验——lab1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

主要学习内容:

  • 工厂的注册、创建和覆盖机制
  • 域的自动化以及uvm_object的常用方法
  • phase机制
  • config机制
  • 消息管理

提示:以下是本篇文章正文内容,下面案例可供参考

一、工厂的注册、创建和覆盖机制

uvm只有两种注册宏:

  • `uvm_object_utils(T)
  • `uvm_component_utils(T)

UVM所有的类都继承于uvm_object或uvm_component类因此只需要两种注册宏。

添加factory_mechanism.sv,编译,输入仿真命令:

vsim -novopt -classdebug +UVM_TESTNAME=object_create work.factory_mechanism

+UVM_TESTNAME=<test_name>它的作用等同于lab0中的run_test(“test_name”),在仿真命令添加测试用例便于后续修改。
上述命令就是运行测试object_create
在这里插入图片描述

1.1完成类型创建

使用不同的方法完成对t1、t2、t3、t4uvm_object类的对象的创建

  • 方法一:
    new(string name)
    在这里插入图片描述
  • 方法二:
    uvm_object::type_id::create(string name)
    👻该方法第一个参数是实例名称,创建uvm_object类型只有一个参数
    在这里插入图片描述
  • 方法三:uvm_factory.create_object_by_name(uvm_object_wrapper requested_type,,string parent_inst_path="", string name)
    在这里插入图片描述
    👻此方法是直接通过工厂调用第一个参数指的是创建并返回的请求创建对象的类型(指导手册上写的the requested_type is a handle to the type’s proxy object不太理解这个 type’s proxy是什么意思),必须是uvm_object的子类,在这里指的是trans类型,通过trans::get_type()得到;第二个参数是结构层次路径,用于索引实例覆盖,通过调用parent(这里不是指父类)方法即uvm_componnet::get_full_name()方法来得到;第三个参数就是实例名称。
    在这里插入图片描述
  • 方法四:
    uvm_component.create_object (string requested_type_name,string name="");
    在这里插入图片描述
    👻该方法使用的是uvm_component类自带的方法,可以创建uvm_object类型的对象,它实际上也是间接调用工厂创建对象,因此等同于方法三。第一个参数是请求创建对象类型的名称,第二个参数是实例名。
    在这里插入图片描述

需要注意的是方法三、四返回的句柄类型。尝试编译可以发现报错信息,赋值类型不匹配
在这里插入图片描述
【类型创建的都是uvm_object类型的句柄,不能直接赋值给trans类型。需要进行类型转换,$cast即可作为函数调用也可以作为任务调用,作为函数调用时有int类型0/1的返回值,因此需要void’()使得函数转换成无返回值类型才可以单独调用,同时强制类型转换是隐性的赋值,并不是单纯的转换类型就结束了】


使用不同的方法完成对u1、u2、u3、u4uvm_component类的对象的创建,方法同上。
需要注意的是创建uvm_componnet类型时方法三还有一个parent参数。
在这里插入图片描述


结果:
在这里插入图片描述
object_create测试字符串name没有传递进去?不知道为什么打印信息是默认的name,但是trans变量类型创建成功
在这里插入图片描述
component_create测试打印信息没问题,unit组件类型也创建成功但是可以看到u1与其他实例并不在top之下例化,原因可能是因为u1采用的是sv的例化方式,没有通过工厂创建。
在这里插入图片描述
在这里插入图片描述

1.2类型覆盖

在进行类型覆盖时一定要记住,覆盖发生在类型对象创建之前,因此子类调用父类的创建阶段时一定要在覆盖之后调用,此外原始类型必须在工厂注册过。

方法:set_type_override_by_type(uvm_object_wrapper original_type,uvm_object_wrapper override_type,bit replace = 1)
在这里插入图片描述
👻该方法是uvm_factory::set_type_override_by_type方法的便捷办法,直接在uvm_component类调用通过类型type完成覆盖,第一个参数是原始类型,第二个参数是覆盖类型,第三个参数如果之前发生过覆盖,replace若为1,则继续覆盖,否则就不覆盖。
在这里插入图片描述

方法:set_type_override(string original_type_name, string override_type_name,bit replace=1);
在这里插入图片描述
👻该方法是 uvm_factory::set_type_override_by_name方法的便捷办法,通过类型名称完成覆盖,这种方法必须保证注册时的类型type与字符串名字name一致。
在这里插入图片描述


结果:
从打印信息和Object窗口可以看到覆盖语句只对利用工厂创建的对象类型起作用。
在这里插入图片描述
在这里插入图片描述
组件类型的覆盖同样如此。
在这里插入图片描述
在这里插入图片描述
结论:覆盖是利用工厂的机制完成的,因此没有利用工厂创建的对象类型和组件类型自然没办法完成覆盖。


【思考】:去掉trans和unit的宏注册,编译是否出错,为什么?
在这里插入图片描述
通过调用宏注册实现类型定义type_id,接着完成类型注册也就是通过工厂完成type_id的注册;如果注释掉宏注册,type_id就没有在工厂完成定义注册,一旦没有注册,那么就无法通过type_id::create()完成创建(虽然这个函数最终还是通过调用factory的函数)。

二、域的自动化和uvm_object的常用方法

了解常见的域声明相关的宏,以及声明后uvm_object类具有的常见方法。

2.1 域的自动化声明

在uvm_object_methos.sv文件的事务类trans里完成所有成员变量域的自动化,需要注意两点:

  • 多个相同类型变量在域的自动化宏声明时不能一起声明,需要分开
  • 枚举类型变量在宏声明时有三个参数即类型,变量名,数据操作方法,其他类型只有后两个
    在这里插入图片描述

2.2 uvm_object::compare()方法

在object_methods_test测试类里使用uvm_object::compare()方法在run phase阶段完成事物的比较。

方法:<uvm_object lhs>.compare(uvm_object rhs, uvm_comparer comparer = null)
在这里插入图片描述
👻比较两个uvm_object类lhs和rhs的成员变量,成功则返回1,失败返回0;参数comparer是最大输出的错误信息,如果为1,则表示比较出现错误后就不会进行后续比较。设置大一点的comparer可以得到更全面的比较信息。使用uvm_default_comparer.show_max设置参数大小,这里可以直接在object_methods_test类调用uvm_default_comparer原因在于它是uvm_pkg的全局对象,可随时访问。
在这里插入图片描述
这里还用到消息处理方式——宏调用,详见第五节

2.3 自定义uvm_object的方法的回调函数

例如compare()的回调函数do_compare()

方法:
在这里插入图片描述
示例:
mytype = trans

  • 在do_compare方法中例化新的句柄rhs_,它是trans类型,而传递进来的参数rhs是uvm_object类型,因此比较前需要进行句柄类型转换
  • 子类需要调用super.do_compare()确保父类的属性也能比较(前提是有父类properties)
    在这里插入图片描述

在这里插入图片描述

仿真结果,可以看到compare()先执行,然后紧接着调用回调函数do_compare()。
在这里插入图片描述

2.4 uvm_object::copy()、print()方法

方法:
在这里插入图片描述
传递参数为copy的对象
在这里插入图片描述
传递参数为打印机,即打印的方式。默认值为uvm_default_printer,同之前的uvm_default_comparer一样是uvm_pkg的全局变量。除此默认值之外还有uvm_default_table_printer、uvm_default_tree_printer、自定义打印等。
在这里插入图片描述

在这里插入图片描述
结果:
Before copy():
在这里插入图片描述
After copy():
在这里插入图片描述


UVM指导手册在描述uvm_object的常用方法中有这样一句话The compare/copy/print method is not virtual and should not be overloaded in derived classes. To compare/copy/print the fields of a derived class, that class should override the do_copy method意思是这些常用的方法都不是虚方法,子类不能覆盖这些父类方法,如果想进一步进行操作,只能自定义这些方法的回调函数。
总结:域的自动化可以帮助coder快速调用常用方法,无需自己定义,节省大量的code、time

三、config机制

在uvm_confug.sv中完成

  • 接口传递
  • 对象传递
  • 单一变量传递

3.1 接口传递

方法:
uvm_config_db# (virtual interface)::set(...)
uvm_config_db# (virtual interface)::get(...)
在这里插入图片描述
在这里插入图片描述
👻先设置接口传递配置set函数,该函数需要发生在构建测试环境run_test()之前。
前三个参数提供完整的作用域(层次路径),最后一个参数是配置的变量。cntxt一般表示当前层次,通常用uvm_root::get()表示uvm_root的全局顶层实例

在这里插入图片描述

这里使用了通配符*,那么在uvm_test_top层次及以下的所有层次的实例都能获取该接口配置

在这里插入图片描述

class comp2同上,通过这种方式,只要uvm_component类在build phase阶段get到了接口,那么该类的实例都能用。

接口的传递需要注意以下几点:

  • 接口的传递需要发生在run_test()之前,以保证在build phase阶段,virtual interface已经传递进unm_config_db中
  • virtual interface和interface是不一样的,可以看到在声明interface和例化if0时并没有声明virtual,而是在传递的过程中使用的都是virtual interface,即实际接口的句柄。
  • set()和get()的层次路径要保持一致,且#(T)传递类型T一致。

3.2 对象传递

方法:同上,传递类型不再是接口,而是uvm_object

在这里插入图片描述

传递的变量类型是config_db它是uvm_object类,所以是对象传递

在这里插入图片描述

该类的成员变量cfg获得了外部传递进来的配置,comp2同上

3.3 单一变量传递

方法同上,传递类型是该变量的数据类型

在这里插入图片描述
在这里插入图片描述

comp2 同上


仿真结果:
在这里插入图片描述

3.4 总结

  • 接口传递必需先于run_test()
  • uvm_config_db#(T)::set()先于对象创建
  • 配置有优先级,层次越高的优先级越高

四、phase机制

在phase_order.sv中完成comp2和comp3中phase的定义

4.1主要的phase

  • build phase、connect phase、run phase、report phase

在这里插入图片描述

在这里插入图片描述

❓run phase执行顺序怎么会是自顶向下,家人们谁懂啊

4.2 其他phase

  • reset phase、main phase
    在这里插入图片描述
    在这里插入图片描述

想了一下应该是没有问题的,run phase 和 reset phase 一起开始是正常的,main phase 也确实应该在reset phase执行完以后再开始,因为他俩是顺序执行的。1us时run phase 和 reset phase结束,main phase在reset phase 结束后开始,再过1us,结束。所以一共是2us。所以由于这种有些混乱的执行顺序,run phase 不应该与细分的12个其他phase混合使用。

五、消息管理

在uvm_message.sv中完成:

5.1过滤所有消息

在测试用例build phase里屏蔽所有级别的消息,使uvm_message_test及其以下组件的消息在仿真时打印出来。

方法:uvm_component类的方法
在这里插入图片描述
👻此方法递归地设置此组件及其以下所有组件的报告的最大详细级别,此组件subtree中任何详细程度超过此最大值的报告都将被忽略。
在这里插入图片描述
仿真结果:可以看到在设置消息级别UVM_NONE以后,build phase之后的消息都没有打印,如果在end of elaboration phase调用,那么build phase阶段的info都会输出。TEST_DONE不知道是哪来的。
在这里插入图片描述

5.2根据ID过滤所有消息

方法:uvm_component类方法
在这里插入图片描述
👻该方法递归地将指定id的报告给定消息级别。
在这里插入图片描述
仿真结果与5.1一致
在这里插入图片描述

5.3 在顶层过滤消息

在5.1和5.2中仍有CREATE(在消息过滤前创建的info)和TOPTB消息输出,通过uvmroot::get()获取顶层(uvm_test_top?)然后过滤消息。

方法:uvm_root::get().set_report_id_verbosity_hier()
结果一样
在这里插入图片描述
在这里插入图片描述
方法:uvm_root::get().set_report_verbosity_level_hier(UVM_NONE);
TEST_DONE消息没了
在这里插入图片描述

在run_tets()之前调用:所有信息已被过滤。
在这里插入图片描述


关于object_create没有将t2,t3,t4的name没有传递进去的问题

Questa仿真器自带的uvm存在一些问题,导致对象创建时name没办法传递进去。

在这里插入图片描述
在这里插入图片描述
仿真器默认使用uvm-1.1d版本,修改modelsim.ini文件使用uvm1.2版本时仿真会出现下面的错误:
在这里插入图片描述

### 回答1: 《UVM入门进阶实验1文档》是一份用于帮助初学者进一步理解和学习UVM实验指导文档。该文档提供了UVM编程框架的第一个实验,旨在帮助读者熟悉UVM的基本概念和用法。 实验1的目标是创建一个简单的UVM测试环境,并展示如何使用UVM框架进行测试。实验包括以下几个主要步骤: 1. 创建一个UVM测试环境:在这一步骤中,我们需要定义测试环境的结构和组件。包括创建一个顶层测试模块、一个顶层环境模块,以及其他必要的组件,如驱动器、监视器、生成器等。 2. 编写测试用例:在这一步骤中,我们需要编写一个简单的测试用例来验证被测设计的功能。测试用例需要继承自UVM的`uvm_test_case`类,并在`run_phase`中定义测试过程。 3. 编写环境配置:在这一步骤中,我们需要将测试用例和测试环境进行连接,并设置一些必要的运行时参数。通过配置对象的方式,我们可以很方便地配置测试环境中的各个组件。 4. 运行仿真:在这一步骤中,我们需要运行仿真并观察测试结果。通过在测试用例中创建一个sequence对象,我们可以在运行时动态生成测试序列。 《UVM入门进阶实验1文档》详细说明了每一步的具体实现方法,并提供了代码示例和可参考的资源链接。 通过完成实验1,读者可以对UVM的基本概念和使用方法有一个更深入的了解。这将为进一步学习和掌握UVM提供坚实的基础,并为以后的工作打下良好的基础。同时,实验1还可以帮助读者培养UVM编程的思维方式和调试技巧,提高工作效率。 总之,《UVM入门进阶实验1文档》是一份非常有价值的学习资料,通过按照文档的指导完成实验,读者可以在短时间内快速入门并掌握UVM的基本用法。 ### 回答2: 《UVM入门进阶实验1文档》是一本介绍UVM(Universal Verification Methodology)的入门实验指导书。UVM是一种用于验证硬件设计的方法学,它提供了一套面向对象的验证框架,可以用于设计验证的自动化和重用。 本文档首先简要介绍了UVM的概念和特点,然后详细讲解了实验1的内容。实验1主要涉及到UVM中最基础的概念和类的使用方法。首先,介绍了UVM中的基础类,如uvm_component、uvm_object和uvm_sequence等,以及它们的继承关系和功能。然后,介绍了如何创建和管理UVM环境,并讲解了如何使用UVM Testbench中的各种组件来进行设计验证。最后,讲解了一些常用的调试技巧和工具,如波形查看器和消息记录器等。 在实验1中,学员将通过几个简单的示例,来熟悉UVM的基本概念和使用方法。例如,学员将学习如何创建一个简单的UVM Testbench,并使用UVM的配置机制来对其进行配置。此外,学员还将学习如何创建和管理UVM Sequences,并在Testbench中使用它们来生成随机的输入数据。最后,学员将学习如何使用UVM里的Transaction来封装输入输出数据,以及如何使用Scoreboard来进行结果验证。 通过完成实验1,学员将掌握UVM中最基本的概念和使用方法,为后续的进阶实验打下基础。同时,学员将对UVM的工作原理和设计验证的流程有一个清晰的认识,为进一步深入学习和应用UVM提供了基础。 ### 回答3: 《UVM入门进阶实验1文档》是一份详细介绍了如何使用UVM进行验证的教程。UVM是一种用于硬件验证的开放式框架,能够帮助工程师更高效地开发和执行验证环境。 该文档首先简要介绍了UVM的背景和原理,包括UVM Testbench的组成结构和工作流程。然后,文档逐步指导读者完成实验1,并提供了实验所需的样例代码和测试平台。 在实验1中,文档首先指导读者创建一个简单的UVM环境,并介绍了UVM的基本类和功能。然后,通过一个简单的例子演示了如何创建一个UVM测试,包括定义测试类、产生和驱动测试向量、分析和比较结果等。读者可以按照文档提供的步骤和示例代码,逐步完成实验。 在实验进行过程中,文档还不断提供了一些常见问题和解决方法。这些问题和解决方法能够帮助读者更好地理解和应用UVM,解决遇到的困惑和难题。 该文档还包括对实验的详细说明和解析,比如UVM环境的搭建、测试向量的生成和分析等。通过这些详细说明和解析,读者可以更深入地理解UVM的工作原理和实现方式。 总之,《UVM入门进阶实验1文档》是一份非常实用的教程,帮助读者快速入门和进阶使用UVM进行硬件验证。通过该文档的学习和实验,读者能够掌握UVM的基本概念和使用方法,为日后的硬件验证工作打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值