在验证平台中加入reference model、scoreboard等之前,思考一个问题:假设这些组件已经定义好了,那么在验证平台的什么位置对它们进行实例化呢?在top_tb中使用run_test进行实例化显然是不行的,因为run_test函数虽然强大,但也只能实例化一个实例;如果在top_tb中使用2.2.1节中实例化driver的方式显然也不可行,因为run_test相当于在top_tb结构层次之外建立一个新的结构层次,而2.2.1节的方式则是基于top_tb的层次结构,如果基于此进行实例化,那么run_test的引用也就没有太大的意义了;如果在driver中进行实例化则更加不合理。

这个问题的解决方案是引入一个容器类,在这个容器类中实例化driver、monitor、reference model和scoreboard等。在调用run_test时,传递的参数不再是my_driver,而是这个容器类,即让UVM自动创建这个容器类的实例。在UVM中,这个容器类称为uvm_env:

代码清单 2-25
文件:src/ch2/section2.3/2.3.2/my_env.sv

4 class my_env extends uvm_env;
5
6 my_driver drv;
7
8 function new(string name = "my_env", uvm_component parent);
9 super.new(name, parent);
10 endfunction
11
12 virtual function void build_phase(uvm_phase phase);
13 super.build_phase(phase);
14 drv = my_driver::type_id::create("drv", this);
15 endfunction
16
17 `uvm_component_utils(my_env)
18 endclass

所有的env应该派生自uvm_env,且与my_driver一样,容器类在仿真中也是一直存在的,使用uvm_component_utils宏来实现factory的注册。

在my_env的定义中,最让人难以理解的是第14行drv的实例化。这里没有直接调用my_driver的new函数,而是使用了一种古怪的方式。这种方式就是factory机制带来的独特的实例化方式。只有使用factory机制注册过的类才能使用这种方式实例化;只有使用这种方式实例化的实例,才能使用后文要讲述的factory机制中最为强大的重载功能。验证平台中的组件在实例化时都应该使用type_name::type_id::create的方式。

在drv实例化时,传递了两个参数,一个是名字drv,另外一个是this指针,表示my_env。回顾一下my_driver的new函数:

代码清单 2-26
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfuncti

这个new函数有两个参数,第一个参数是实例的名字,第二个则是parent。由于my_driver在uvm_env中实例化,所以my_driver的父结点(parent)就是my_env。通过parent的形式,UVM建立起了树形的组织结构。在这种树形的组织结构中,由run_test创建的实例是树根(这里是my_env),并且树根的名字是固定的,为uvm_test_top,这在前文中已经讲述过;在树根之后会生长出枝叶(这里只有my_driver),长出枝叶的过程需要在my_env的build_phase中手动实现。无论是树根还是树叶,都必须由uvm_component或者其派生类继承而来。整棵UVM树的结构如图2-3所示。

当加入了my_env后,整个验证平台中存在两个build_phase,一个是my_env的,一个是my_driver的。那么这两个build_phase按照何种顺序执行呢?在UVM的树形结构中,build_phase的执行遵照从树根到树叶的顺序,即先执行my_env的build_phase,再执行my_driver的build_phase。当把整棵树的build_phase都执行完毕后,再执行后面的phase。

my_driver在验证平台中的层次结构发生了变化,它一跃从树根变成了树叶,所以在top_tb中使用config_db机制传递virtual my_if时,要改变相应的路径;同时,run_test的参数也从my_driver变为了my_env:

代码清单 2-27
文件:src/ch2/section2.3/2.3.2/top_tb.sv

42 initial begin
43 run_test("my_env");
44 end
45
46 initial begin
47 uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.drv", "vif", inp ut_if);
48 end

set函数的第二个参数从uvm_test_top变为了uvm_test_top.drv,其中uvm_test_top是UVM自动创建的树根的名字,而drv则是在my_env的build_phase中实例化drv时传递过去的名字。如果在实例化drv时传递的名字是my_drv,那么set函数的第二个参数中也应该是my_drv:

代码清单 2-28
class my_env extends uvm_env

drv = my_driver::type_id::create("my_drv", this);

endclass module top_tb;

initial begin
uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.my_drv", "vif", inpu t_if);
end
endmodule

*2.3.2_加入env的更多相关文章

  1. laravel中如何防止直接访问.env文件

    .env文件含有数据库账号密码等敏感数据,在laravel5.2中,在本地访问127.0.0.1/laravel/.env可直接访问到.env. 为避免.env被直接访问,可使用重定向,方法如下: 在 ...

  2. jni调试3(线程调试env变量问题)

    jni层调试线程死机原因 一,导致死机原因:   jni层中  线程函数中  只要添加调用env 的函数 ,,就会死机     二,解决方法 第一我们应该理解: ①(独立性) JNIEnv 是一个与线 ...

  3. 【Junit 报错】No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).

    Junit报错 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvi ...

  4. express+gulp构建项目(四)env环境变量

    这里的文件的作用是负责设置env环境变量和日志. index.js try { require('dotenv').load({silent: true}); //dotenv从一个.env文件中读取 ...

  5. DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  6. #!/usr/bin/env python与#!/usr/bin/python的区别

    [摘自:http://blog.csdn.net/wh_19910525/article/details/8040494] 一般的python文件的开头都有#!/usr/bin/python.这是什么 ...

  7. java:comp/env/jdbc/ 的两种配置方法

    1. 在 META-INF 下建立文件: context.xml <?xml version="1.0" encoding="UTF-8"?> &l ...

  8. Cannot install NodeJs: /usr/bin/env: node: No such file or directory

    安装doxmate时,doxmate地址是:https://github.com/JacksonTian/doxmatenpm install doxmate -g 安装完后把错误:Cannot in ...

  9. ADF_Data Binding系列2_使用URL Service Data Control

    2015-02-16 Created By BaoXinjian

随机推荐

  1. Solr中的一些查询参数

    fl: 是逗号分隔的列表,用来指定文档结果中应返回的 Field 集.默认为 “*”,指所有的字段. defType: 指定query parser,常用defType=lucene, defType ...

  2. 记一次很坑的python2与python3共存问题

    当添加PYTHONPATH环境变量时,无论输入pip2 -V还是pip3 -V都显示的是python2的环境变量,使用pip3 install 时也是安装在了python2的三方库(因为python2 ...

  3. .Net C# 阿拉伯数字转为中文金额数字

    一个练习,将阿拉伯数字转为中文金额数字,针对包含整数的金额有问题 代码: public string ReturnStr(string inputNum) { ", }; string[] ...

  4. C# winform中listview排序

    本文解决方案是采用下面链接中的解决方案.十分感谢这篇文章的作者bright:http://blog.163.com/shensc@126/blog/static/1312896522010614103 ...

  5. fd - 更好的 find 命令

    欢迎关注我的公众号 spider-learn fd(https://github.com/sharkdp/fd) 是 find 命令的一个更现代的替换. 对比一下 查找名字含有某个字符的文件 OLD ...

  6. Usboot V1.68版本

    V1.68版本,我的收藏之一 官方的介绍: 市面上现在大多数U盘都支持启动机器的功能,但是要制作启动型U盘,需要进入WIN98,现在很多人机器 上都没有98了吧,呵呵.为了做个启动盘,装一个98,多冤 ...

  7. 【C++对象模型】使用gcc、clang和VC++显示C++类的内存布局

    引言 各种C++实现对C++类/对象的内存布局可能有所不同,包括数据成员的顺序.虚函数表(virtual table: vtbl)的结构.继承关系的处理等.了解C++类/对象的布局,对于理解C++各种 ...

  8. 我从Linux走来,选择了Windows

    我从Linux走来,选择了Windows 几天前就想提笔写下这篇,理解很多人一定会对言论不苟同. 但是我相信您看完一个一年多的Linux用户写完的以后,一定也不会太反对 一.为什么我成为一名 Linu ...

  9. python基础知识梳理-----4基本数据类型,list ,tuple 操作 ,增删该查,以及其他功能函数

    一:列表的增加 1: append() lis = ['张三','李四','王二码子','李鹏智障'] lis.append('赵武')      # 这种加法是放在最后 print(lis) 输出  ...

  10. C++基础知识:成员函数、对象拷贝、私有成员

    一.综述 类是我们自己定义的数据类型(新类型) 设计类时要考虑的角度: (1)站在设计和实现者的角度来考虑 (2)站在使用者的角度来考虑 (3)父类,子类 二.类基础 (1)一个类就是一个用户自己定义 ...