UVM建造测试用例

news2024/11/29 19:49:19

(1)加入base_test

        在一个实际应用的UVM验证平台中,my_env并不是树根,通常来说,树根是一个基于uvm_test派生的类真正的测试用例都是基于base_test派生的一个类

class base_test extends uvm_test;

   my_env         env;
   
   function new(string name = "base_test", uvm_component parent = null);
      super.new(name,parent);
   endfunction
   
   extern virtual function void build_phase(uvm_phase phase);
   extern virtual function void report_phase(uvm_phase phase);
   `uvm_component_utils(base_test)
endclass


function void base_test::build_phase(uvm_phase phase);
   super.build_phase(phase);
   env  =  my_env::type_id::create("env", this); 
   uvm_config_db#(uvm_object_wrapper)::set(this,
                                           "env.i_agt.sqr.main_phase",
                                           "default_sequence",
                                            my_sequence::type_id::get());
endfunction

function void base_test::report_phase(uvm_phase phase);
   uvm_report_server server;
   int err_num;
   super.report_phase(phase);

   server = get_report_server();
   err_num = server.get_severity_count(UVM_ERROR);

   if (err_num != 0) begin
      $display("TEST CASE FAILED");
   end
   else begin
      $display("TEST CASE PASSED");
   end
endfunction

        base_test派生自uvm_test,使用uvm_component_utils宏来注册到factory中。在build_phase中实例化my_env,并设置sequencer的 default_sequence。需要注意的是,这里设置了default_sequence,其他地方就不需要再设置了。
        除了实例化env外,base_test中做的事情在不同的公司各不相同。上面的代码中出现了report_phase,在report_phase中根据 UVM_ERROR的数量来打印不同的信息。一些日志分析工具可以根据打印的信息来判断DUT是否通过了某个测试用例的检查。report_phase也是UVM内建的一个phase,它在main_phase结束之后执行。
        除了上述操作外,还通常在base_test中做如下事情:第一,设置整个验证平台的超时退出时间;第二,通过config_db设置验 证平台中某些参数的值。这些根据不同的验证平台及不同的公司而不同,没有统一的答案。
        在把my_env放入base_test中之后,UVM树的层次结构变为如图2-11所示的形式。
        top_tb中run_test的参数从my_env变成了base_test,并且config_db中设置virtual interface的路径参数要做如下改变:

 

initial begin
   run_test("base_test");
end

initial begin
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "vif", input_if);
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.mon", "vif", input_if);
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt.mon", "vif", output_if);
end

(2)UVM中测试用例的启动

        要测试一个DUT是否按照预期工作,需要对其施加不同的激励,这些激励被称为测试向量或pattern。一种激励作为一个测试 用例,不同的激励就是不同的测试用例。测试用例的数量是衡量验证人员工作成果的最直接目标。
        伴随着验证的进行,测试用例的数量一直在增加,在增加的过程中,很重要的一点是保证后加的测试用例不影响已经建好的 测试用例。在前面所有的例子中,通过设置default_sequence的形式启动my_sequence。假如现在有另外一个my_sequence2,如何在 不影响my_sequence的前提下将其启动呢?最理想的办法是在命令行中指定参数来启动不同的测试用例。
        无论是在my_env中设置default_sequence,还是在base_test中或者top_tb中设置,都必须修改相关的设置代码才能启动 my_sequence2,这与预期相去甚远。为了解决这个问题,先来看两个不同的测试用例。my_case0的定义如下:

`ifndef MY_CASE0__SV
`define MY_CASE0__SV
class case0_sequence extends uvm_sequence #(my_transaction);
   my_transaction m_trans;

   function  new(string name= "case0_sequence");
      super.new(name);
   endfunction 
   
   virtual task body();
      if(starting_phase != null) 
         starting_phase.raise_objection(this);
      repeat (10) begin
         `uvm_do(m_trans)
      end
      #100;
      if(starting_phase != null) 
         starting_phase.drop_objection(this);
   endtask

   `uvm_object_utils(case0_sequence)
endclass


class my_case0 extends base_test;

   function new(string name = "my_case0", uvm_component parent = null);
      super.new(name,parent);
   endfunction 
   extern virtual function void build_phase(uvm_phase phase); 
   `uvm_component_utils(my_case0)
endclass


function void my_case0::build_phase(uvm_phase phase);
   super.build_phase(phase);

   uvm_config_db#(uvm_object_wrapper)::set(this, 
                                           "env.i_agt.sqr.main_phase", 
                                           "default_sequence", 
                                           case0_sequence::type_id::get());
endfunction

`endif

my_case1的定义如下:

`ifndef MY_CASE1__SV
`define MY_CASE1__SV
class case1_sequence extends uvm_sequence #(my_transaction);
   my_transaction m_trans;

   function  new(string name= "case1_sequence");
      super.new(name);
   endfunction 

   virtual task body();
      if(starting_phase != null) 
         starting_phase.raise_objection(this);
      repeat (10) begin
         `uvm_do_with(m_trans, { m_trans.pload.size() == 60;})
      end
      #100;
      if(starting_phase != null) 
         starting_phase.drop_objection(this);
   endtask

   `uvm_object_utils(case1_sequence)
endclass

class my_case1 extends base_test;
  
   function new(string name = "my_case1", uvm_component parent = null);
      super.new(name,parent);
   endfunction 
   
   extern virtual function void build_phase(uvm_phase phase); 
   `uvm_component_utils(my_case1)
endclass


function void my_case1::build_phase(uvm_phase phase);
   super.build_phase(phase);

   uvm_config_db#(uvm_object_wrapper)::set(this, 
                                           "env.i_agt.sqr.main_phase", 
                                           "default_sequence", 
                                           case1_sequence::type_id::get());
endfunction

`endif

        在case1_sequence中出现了uvm_do_with宏,它是uvm_do系列宏中的一个,用于在随机化时提供对某些字段的约束
        要启动my_case0,需要在top_tb中更改run_test的参数:

initial begin
run_test("my_case0");
end

        而要启动my_case1,也需要更改:

initial begin
run_test("my_case1");
end

        当my_case0运行的时候需要修改代码,重新编译后才能运行;当my_case1运行时也需如此,这相当不方便。事实上,UVM提 供对不加参数的run_test的支持:

initial begin
   run_test();
end

        在这种情况下,UVM会利用UVM_TEST_NAME从命令行中寻找测试用例的名字,创建它的实例并运行。如下所示的代码可 以启动my_case0:

<sim command>
… +UVM_TEST_NAME=my_case0

        而如下所示的代码可以启动my_case1:

<sim command>
… +UVM_TEST_NAME=my_case1

        整个启动及执行的流程如下图所示

                                                图1 测试用例的启动及执行流程
启动后,整棵UVM树的结构如下图所示。

                                        图2 每个测试用例建立的UVM树

        图2-13与图2-11的唯一区别在于树根的类型从base_test变成了my_casen。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rpm安装gitlab

1.rpm包下载 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 2.进行安装 rpm -ivh gitlab-ce-15.9.7-ce.0.el7.x86_64.rpm --nodeps --force 3.配置访问地址 vim /etc/gitlab/gitlab.rb 4.重新加载配置以及重启服务 gitlab-ctl reconfiguregitlab-ctl resta…

指针(进阶)

指针进阶&#xff1a; 通过指针基础我们已经了解了指针&#xff0c;这篇文章我们会举大量的例子&#xff0c;使我们对指针透彻理解&#xff0c;我们下来看一段代码&#xff1a; int main() {char a[] "ab";char* pc a;printf("%c\n", *pc);printf("…

指定分隔符对字符串进行分割 numpy.char.split()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定分隔符对字符串进行分割 numpy.char.split() 选择题 请问下列程序运行的的结果是&#xff1a; import numpy as np print("【执行】np.char.split(I.Love.China, sep .)") p…

GNSEC 2022年第8届全球下一代软件工程线上峰会-核心PPT资料下载

一、峰会简介 新一代软件工程是指利用新的理论、方法和技术&#xff0c;在软件开发、部署、运维等过程中&#xff0c;实现软件的可控、可预测、可维护的软件生产方式。它涵盖了多个领域&#xff0c;如软件开发、测试、部署、运维等&#xff0c;旨在提高软件生产效率和质量。 …

13款趣味性不错(炫酷)的前端动画特效及源码(预览获取)分享(附源码)

文字激光打印特效 基于canvas实现的动画特效&#xff0c;你既可以设置初始的打印文字也可以在下方输入文字可实现激光字体打印&#xff0c;精简易用。 预览获取 核心代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&q…

Windows server 部署iSCSI共享磁盘搭建故障转移群集

在域环境下&#xff0c;在域控制器中配置iSCSI服务&#xff0c;配置共享网络磁盘&#xff0c;在节点服务器使用共享磁盘&#xff0c;并在节点服务器中搭建故障转移群集&#xff0c;实现故障转移 环境准备 准备3台服务器&#xff0c;配置都是8g2核&#xff0c;50g硬盘&#xf…

SpringBoot 属性配置解析

属性配置介绍 spring官方提供的17中属性配置的方式 Devtools全局配置测试环境TestPropertySource注解测试环境properties属性命令行参数SPRING_APPLICATION_JSON属性ServletConfig初始化参数ServletContext初始化参数JNDI属性JAVA系统属性操作系统环境变量RandomValueProperty…

9大高效的前端测试工具与框架!

在每个Web应用程序中&#xff0c;作为用户直接可见的应用程序外观&#xff0c;“前端”包括&#xff1a;图形化的用户界面、相应的功能、及其整体站点的可用性。我们可以毫不夸张地说&#xff1a;如果前端无法正常工作&#xff0c;您将无法“拉新”网站的潜在用户。这也正是我们…

HarmonyOS4.0从零开始的开发教程02初识ArkTS开发语言(上)

HarmonyOS&#xff08;二&#xff09;初识ArkTS开发语言&#xff08;上&#xff09;之TypeScript入门 前言 Mozilla创造了JS&#xff0c;Microsoft创建了TS&#xff0c;而Huawei进一步推出了ArkTS。因此在学习使用ArkTS前&#xff0c;需要掌握基本的TS开发技能。 从最初的基…

Kafka 的消息格式:了解消息结构与序列化

Kafka 作为一款高性能的消息中间件系统&#xff0c;其消息格式对于消息的生产、传输和消费起着至关重要的作用。本篇博客将深入讨论 Kafka 的消息格式&#xff0c;包括消息的结构、序列化与反序列化&#xff0c;以及一些常用的消息格式选项。通过更丰富的示例代码和深入的解析&…

人工智能-编译器和解释器

编译器和解释器 命令式编程使用诸如print、“”和if之类的语句来更改程序的状态。 考虑下面这段简单的命令式程序&#xff1a; def add(a, b):return a bdef fancy_func(a, b, c, d):e add(a, b)f add(c, d)g add(e, f)return gprint(fancy_func(1, 2, 3, 4)) 10 Python…

【分布式微服务专题】从单体到分布式(一、SpringCloud项目初步升级)

目录 前言阅读对象阅读导航前置知识笔记正文一、单体服务介绍二、服务拆分三、分布式微服务升级前的思考3.1 关于SpringBoot/SpringCloud的思考【有点门槛】 四、SpringCloud升级整合4.1 新建父子项目 学习总结感谢 前言 从本节课开始&#xff0c;我将自己手写一个基于SpringC…

谷歌刚刚发布了Gemini 1.0,采用了OpenAI的GPT4

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 对于谷歌和安卓来说&#xff0c;这是一个重要时刻。谷歌刚刚发布了 Gemini 1.0&#xff0c;这是其最新的LLM&#xff0c;它采用了 OpenAI 的 GPT4。 共有三种不同…

WPF仿网易云搭建笔记(0):项目搭建

文章目录 前言项目地址项目Nuget包搭建项目初始化项目架构App.xaml引入MateralDesign资源包 项目初步分析将标题栏去掉DockPanel初步布局 资源字典举例 结尾 前言 最近在找工作&#xff0c;发现没有任何的WPF可以拿的出手的工作经验&#xff0c;打算仿照网易云搭建一个WPF版本…

深度解析 Kafka 中的 Offset 管理与最佳实践

Kafka 中的 Offset&#xff08;偏移量&#xff09;是消息处理的关键元素&#xff0c;对于保证消息传递的可靠性和一致性至关重要。本篇博客将深度解析 Kafka 中的 Offset 管理机制&#xff0c;并提供丰富的示例代码&#xff0c;让你更全面地理解 Offset 的原理、使用方法以及最…

鸿蒙Harmony ArkUI十大开源项目

一 OH哔哩 https://gitee.com/ohos_port/ohbili 项目简介 【OH哔哩】是一款基于OpenHarmony系统ArkUI框架开发的哔哩哔哩动画第三方客户端 用到的三方库 bilibili-API-collect 哔哩哔哩-API收集整理ohos_ijkplayer 基于FFmpeg的视频播放器PullToRefresh 下拉刷新、上拉加载组件…

html通过CDN引入Vue组件抽出复用

html通过CDN引入Vue组件抽出复用 近期遇到个需求&#xff0c;就是需要在.net MVC的项目中&#xff0c;对已有的项目的首页进行优化&#xff0c;也就是写原生html和js。但是咱是一个写前端的&#xff0c;写html还可以&#xff0c;.net的话&#xff0c;开发也不方便&#xff0c;还…

CleanMyMac X4.15.0最新官方和谐版下载

Mac系统进行文件清理&#xff0c;一般是直接将文件拖动入“废纸篓”回收站中&#xff0c;然后通过清理回收站&#xff0c;就完成了一次文件清理的操作&#xff0c;但是这么做并无法保证文件被彻底删除了&#xff0c;有些文件通过一些安全恢复手段依旧是可以恢复的&#xff0c;那…

持续集成交付CICD: Sonarqube REST API 查找与新增项目

目录 一、实验 1.SonarQube REST API 查找项目 2.SonarQube REST API 新增项目 一、实验 1.SonarQube REST API 查找项目 &#xff08;1&#xff09;Postman测试 转换成cURL代码 &#xff08;2&#xff09;Jenkins添加凭证 &#xff08;3&#xff09;修改流水线 pipeline…

解决finalshell右键选择粘贴后出现直接执行的问题

文章目录 已经找到问题原因我的问题错误的解决 已经找到问题原因 复制的时候&#xff0c;只复制名字&#xff0c;不要复制后面多出来的东西&#xff0c;不然会自动加上回车换行 我的问题 我当时是想通过 ls -l 查出jdk的文件后&#xff0c; 复制文件名就不用看着敲了&#x…