摘自: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的更多相关文章

  1. 计算机网络七层协议模型 “开放系统互联参考模型”,即著名的OSI/RM模型(Open System Interconnection/Reference Model)

    计算机网络七层协议模型 作者:Ryan    时间:2013年10月7日 一.物理层(Physical Layer) OSI模型的最低层或第一层,规定了激活.维持.关闭通信端点之间的机械特性.电气特性 ...

  2. 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 ...

  3. PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)

    100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...

  4. 前端学HTTP之网络基础

    × 目录 [1]网络 [2]OSI [3]TCP/IP 前面的话 HTTP协议对于前端工程师是非常重要的.我们在浏览网站时,访问的每一个WEB页面都需要使用HTTP协议实现.如果不了解HTTP协议,就 ...

  5. 【转】TCP/IP协议栈及OSI参考模型详解

    OSI参考模型 OSI RM:开放系统互连参考模型(open systeminterconnection reference model) OSI参考模型具有以下优点: 简化了相关的网络操作: 提供设 ...

  6. Python黑帽编程3.0 第三章 网络接口层攻击基础知识

    3.0 第三章 网络接口层攻击基础知识 首先还是要提醒各位同学,在学习本章之前,请认真的学习TCP/IP体系结构的相关知识,本系列教程在这方面只会浅尝辄止. 本节简单概述下OSI七层模型和TCP/IP ...

  7. [Network] 计算机网络基础知识总结

    计算机网络学习的核心内容就是网络协议的学习.网络协议是为计算机网络中进行数据交换而建立的规则.标准或者说是约定的集合.因为不同用户的数据终端可能采取的字符集是不同的,两者需要进行通信,必须要在一定的标 ...

  8. 《Web全栈工程师的自我修养》读书笔记(转载)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/5 ...

  9. ( 转)UVM验证方法学之一验证平台

    在现代IC设计流程中,当设计人员根据设计规格说明书完成RTL代码之后,验证人员开始验证这些代码(通常称其为DUT,Design Under Test).验证工作主要保证从设计规格说明书到RTL转变的正 ...

随机推荐

  1. TFS (Team Foundation Server) 2013集成Maven构建

    Team Foundation Server原生就支持跨平台的构建,包括Ant和Maven两种构建方式.通过配置构建服务器,连接TFS源代码库,可以实现持续集成构建,自动检测代码库健康状况,进而实现自 ...

  2. [C#]C#中ToString()和Convert.ToString()的区别

    一.一般用法说明 ToString()是Object的扩展方法,所以都有ToString()方法;而Convert.ToString(param)(其中param参数的数据类型可以是各种基本数据类型, ...

  3. [Java]java内存及数据区

    Java运行时的数据区包括:(其中前两个是线程共享的) 1.方法区(Method Area) 存储已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据 2.堆(Heap) 存放对象实例 ...

  4. 纸壳CMS列表Grid的配置

    纸壳CMS(ZKEACMS)里的Grid是一个TagHelper,是对jQuery插件datatables的一个配置封装. Easy.Mvc.TagHelpers.GridTagHelper grid ...

  5. 使用ubuntu搭建时间机器备份服务

    如何在ubuntu下搭建时间备份服务 折腾了很久,终于可以了. 请严格按照下面的方式来操作. 真正明白问题的,可以按照自己的思路来. 我用的是ubnutu 16.04 安装配置netatalk sud ...

  6. 知物由学 | AI网络安全实战:生成对抗网络

    本文由  网易云发布. “知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道.“知物由学” ...

  7. spring利用注解方式实现Java读取properties属性值

    1. 建立properties文件:我在resource下面建立一个config文件夹,config文件夹里面有mytest.properties文件,文件内容如下: sam.username=sam ...

  8. linux系统无法启动,提示give root password for maintenance错误

    电脑的虚拟机安装的是centos6.2操作系统,今天打开虚拟机时候,提示 give root password for maintenance (or type control-D to contin ...

  9. 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例

    前提 Cordova Android 7.0.0开始改变了项目安卓平台的架构.新建一个空项目分别添加Android 6.4.0 和 Android 7.0.0平台: cordova platform ...

  10. C语言多线程编程一

    1. Windows下同时打开多个对话框: #include <Windows.h> #include <process.h> //创建线程 void runmsg(void ...