*2_3_5_加入reference model
摘自:http://book.2cto.com/201408/46009.html
在2.1节中讲述验证平台的框图时曾经说过,reference model用于完成和DUT相同的功能。
reference model的输出被scoreboard接收,用于和DUT的输出相比较。DUT如果很复杂,那么reference model也会相当复杂。
本章的DUT很简单,所以reference model也相当简单:
文件:src/ch2/section2.3/2.3.5/my_model.sv
4 class my_model extends uvm_component;
5
6 uvm_blocking_get_port #(my_transaction) port;
7 uvm_analysis_port #(my_transaction) ap;
8
9 extern function new(string name, uvm_component parent);
10 extern function void build_phase(uvm_phase phase);
11 extern virtual task main_phase(uvm_phase phase);
12
13 `uvm_component_utils(my_model)
14 endclass
15
16 function my_model::new(string name, uvm_component parent);
17 super.new(name, parent);
18 endfunction
19
20 function void my_model::build_phase(uvm_phase phase);
21 super.build_phase(phase);
22 port = new("port", this);
23 ap = new("ap", this);
24 endfunction
25
26 task my_model::main_phase(uvm_phase phase);
27 my_transaction tr;
28 my_transaction new_tr;
29 super.main_phase(phase);
30 while(1) begin
31 port.get(tr);
32 new_tr = new("new_tr");
33 new_tr.my_copy(tr);
34 `uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)
35 new_tr.my_print();
36 ap.write(new_tr);
37 end
38 endtask
在my_model的main_phase中,只是单纯地复制一份从i_agt得到的tr,并传递给后级的scoreboard中。my_copy是一个在my_transaction中定义的函数,其代码为:
代码清单 2-42
文件:src/ch2/section2.3/2.3.5/my_transaction.sv
41 function void my_copy(my_transaction tr);
42 if(tr == null)
43 `uvm_fatal("my_transaction", "tr is null!!!!")
44 dmac = tr.dmac;
45 smac = tr.smac;
46 ether_type = tr.ether_type;
47 pload = new[tr.pload.size()];
48 for(int i = 0; i < pload.size(); i++) begin
49 pload[i] = tr.pload[i];
50 end
51 crc = tr.crc;
52 endfunction
这里实现了两个my_transaction的复制。
完成my_model的定义后,需要将其在my_env中实例化。其实例化方式与agent、driver相似,这里不具体列出代码。在加入my_model后,整棵UVM树变成了如图2-7所示的形式。
my_model并不复杂,这其中令人感兴趣的是my_transaction的传递方式。my_model是从i_agt中得到my_transaction,并把my_transaction传递给my_scoreboard。在UVM中,通常使用TLM(Transaction Level Modeling)实现component之间transaction级别的通信。
要实现通信,有两点是值得考虑的:
第一,数据是如何发送的?
第二,数据是如何接收的?
在UVM的transaction级别的通信中,数据的发送有多种方式,其中一种是使用uvm_analysis_port。在my_monitor中定义如下变量:
代码清单 2-43
文件:src/ch2/section2.3/2.3.5/my_monitor.sv
7 uvm_analysis_port #(my_transaction) ap;
uvm_analysis_port是一个参数化的类,其参数就是这个analysis_port需要传递的数据的类型,在本节中是my_transaction。
声明了ap后,需要在monitor的build_phase中将其实例化:
代码清单 2-44
文件:src/ch2/section2.3/2.3.5/my_monitor.sv
14 virtual function void build_phase(uvm_phase phase);
…
18 ap = new("ap", this);
19 endfunction
在main_phase中,当收集完一个transaction后,需要将其写入ap中:
代码清单 2-45
task my_monitor::main_phase(uvm_phase phase);
my_transaction tr;
while(1) begin
tr = new("tr");
collect_one_pkt(tr);
ap.write(tr);
end
endtask
write是uvm_analysis_port的一个内建函数。
到此,在my_monitor中需要为transaction通信准备的工作已经全部完成。
UVM的transaction级别通信的数据接收方式也有多种,其中一种就是使用uvm_blocking_get_port。这也是一个参数化的类,其参数是要在其中传递的transaction的类型。在my_model的第6行中,定义了一个端口,并在build_phase中对其进行实例化。
在main_phase中,通过port.get任务来得到从i_agt的monitor中发出的transaction。
在my_monitor和my_model中定义并实现了各自的端口之后,通信的功能并没有实现,还需要在my_env中使用fifo将两个端口联系在一起。在my_env中定义一个fifo,并在build_phase中将其实例化:
代码清单 2-46
文件:src/ch2/section2.3/2.3.5/my_env.sv
10 uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;
…
23 agt_mdl_fifo = new("agt_mdl_fifo", this);
fifo的类型是uvm_tlm_analysis_fifo,它本身也是一个参数化的类,其参数是存储在其中的transaction的类型,这里是my_transaction。
之后,在connect_phase中将fifo分别与my_monitor中的analysis_port和my_model中的blocking_get_port相连:
代码清单 2-47
文件:src/ch2/section2.3/2.3.5/my_env.sv
31 function void my_env::connect_phase(uvm_phase phase);
32 super.connect_phase(phase);
33 i_agt.ap.connect(agt_mdl_fifo.analysis_export);
34 mdl.port.connect(agt_mdl_fifo.blocking_get_export);
35 endfunction
这里引入了connect_phase。与build_phase及main_phase类似,connect_phase也是UVM内建的一个phase,它在build_phase执行完成之后马上执行。
与build_phase不同的是,connect_phase的执行顺序并不是从树根到树叶,而是从树叶到树根——先执行driver和monitor的connect_phase,再执行agent的connect_phase,最后执行env的connect_phase。
为什么这里需要一个fifo呢?不能直接把my_monitor中的analysis_port和my_model中的blocking_get_port相连吗?
由于analysis_port是非阻塞性质的,ap.write函数调用完成后马上返回,不会等待数据被接收。假如当write函数调用时,blocking_get_port正在忙于其他事情,而没有准备好接收新的数据时,此时被write函数写入的my_transaction就需要一个暂存的位置,这就是fifo。
在如上的连接中,用到了i_agt的一个成员变量ap,它的定义与my_monitor中ap的定义完全一样:
代码清单 2-48
文件:src/ch2/section2.3/2.3.5/my_agent.sv
8 uvm_analysis_port #(my_transaction) ap;
与my_monitor中的ap不同的是,不需要对my_agent中的ap进行实例化,而只需要在my_agent的connect_phase中将monitor的值赋给它,换句话说,这相当于是一个指向my_monitor的ap的指针:
代码清单 2-49
文件:src/ch2/section2.3/2.3.5/my_agent.sv
29 function void my_agent::connect_phase(uvm_phase phase);
30 super.connect_phase(phase);
31 ap = mon.ap;
32 endfunction
根据前面介绍的connect_phase的执行顺序,my_agent的connect_phase的执行顺序早于my_env的connect_phase的执行顺序,从而可以保证执行到i_agt.ap.connect语句时,i_agt.ap不是一个空指针。
*2_3_5_加入reference model的更多相关文章
- 计算机网络七层协议模型 “开放系统互联参考模型”,即著名的OSI/RM模型(Open System Interconnection/Reference Model)
计算机网络七层协议模型 作者:Ryan 时间:2013年10月7日 一.物理层(Physical Layer) OSI模型的最低层或第一层,规定了激活.维持.关闭通信端点之间的机械特性.电气特性 ...
- Using an open debug interconnect model to simplify embedded systems design
Using an open debug interconnect model to simplify embedded systems design Tom Cunningham, Freescale ...
- PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)
100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...
- 前端学HTTP之网络基础
× 目录 [1]网络 [2]OSI [3]TCP/IP 前面的话 HTTP协议对于前端工程师是非常重要的.我们在浏览网站时,访问的每一个WEB页面都需要使用HTTP协议实现.如果不了解HTTP协议,就 ...
- 【转】TCP/IP协议栈及OSI参考模型详解
OSI参考模型 OSI RM:开放系统互连参考模型(open systeminterconnection reference model) OSI参考模型具有以下优点: 简化了相关的网络操作: 提供设 ...
- Python黑帽编程3.0 第三章 网络接口层攻击基础知识
3.0 第三章 网络接口层攻击基础知识 首先还是要提醒各位同学,在学习本章之前,请认真的学习TCP/IP体系结构的相关知识,本系列教程在这方面只会浅尝辄止. 本节简单概述下OSI七层模型和TCP/IP ...
- [Network] 计算机网络基础知识总结
计算机网络学习的核心内容就是网络协议的学习.网络协议是为计算机网络中进行数据交换而建立的规则.标准或者说是约定的集合.因为不同用户的数据终端可能采取的字符集是不同的,两者需要进行通信,必须要在一定的标 ...
- 《Web全栈工程师的自我修养》读书笔记(转载)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/5 ...
- ( 转)UVM验证方法学之一验证平台
在现代IC设计流程中,当设计人员根据设计规格说明书完成RTL代码之后,验证人员开始验证这些代码(通常称其为DUT,Design Under Test).验证工作主要保证从设计规格说明书到RTL转变的正 ...
随机推荐
- C#语言各个版本特性(一)
一.c#版本中添加的功能: C#2.0 泛型 部分类型 匿名方法 迭代器 可空类型 Getter / setter单独可访问性 方法组转换(代表) Co- and Contra-variance fo ...
- window下使用MyCat实现简单的读写分离
参考文档 MyCat权威指南 MyCat项目主页 学会数据库读写分离.分表分库--用Mycat,这一篇就够了! MyCat安装 Java SDK下载(必须JDK7或更高版本) MYSQL下载 (MyC ...
- python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型
1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...
- collections模块—— Counter
ounter目的是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value.计数值可以是任意的Interger(包括0和负数).Counter类和 ...
- AcWing 143. 最大异或对
https://www.acwing.com/problem/content/145 #include <iostream> #include <algorithm> usin ...
- Jmeter_RabbitMQ性能测试
[前言] RabbitMQ消息的传递并非使用HTTP协议,而是AMQP协议,因此除非开发暴露一个HTTP请求接口出来,否则无法直接使用HTTP请求发送json串数据,实现数据publish到MQ中. ...
- USB-Redirector-Technician 永久破解版(USB设备映射软件)
USB-Redirector-Technician 这个软件对于搞安卓刷机的人想必非常熟悉,淘宝破解版售价:38 一个的东西 除了远程刷机,用于映射一些小型设备是没问题的,只要网跟得上~ USB-Re ...
- [转] YUM 源优先级插件:Yum Priorities
Linux 发行版比较多,同时还有很多个人或组织维护了某些特定用途的安装/升级源.Yum Priorities 插件可以用来强制保护源.它通过给各个源设定不同的优先级,使得系统管理员可以将某些源(比如 ...
- 2016级算法第六次上机-C.AlvinZH的学霸养成记II
1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时cu ...
- 实验一 c++简单程序设计
一.实验内容 1.ex 2_28 (1) 用if...else判断 #include<iostream> using namespace std; int main() { char i; ...