摘自: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. C#语言各个版本特性(一)

    一.c#版本中添加的功能: C#2.0 泛型 部分类型 匿名方法 迭代器 可空类型 Getter / setter单独可访问性 方法组转换(代表) Co- and Contra-variance fo ...

  2. window下使用MyCat实现简单的读写分离

    参考文档 MyCat权威指南 MyCat项目主页 学会数据库读写分离.分表分库--用Mycat,这一篇就够了! MyCat安装 Java SDK下载(必须JDK7或更高版本) MYSQL下载 (MyC ...

  3. python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型

    1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...

  4. collections模块—— Counter

    ounter目的是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value.计数值可以是任意的Interger(包括0和负数).Counter类和 ...

  5. AcWing 143. 最大异或对

    https://www.acwing.com/problem/content/145 #include <iostream> #include <algorithm> usin ...

  6. Jmeter_RabbitMQ性能测试

    [前言] RabbitMQ消息的传递并非使用HTTP协议,而是AMQP协议,因此除非开发暴露一个HTTP请求接口出来,否则无法直接使用HTTP请求发送json串数据,实现数据publish到MQ中. ...

  7. USB-Redirector-Technician 永久破解版(USB设备映射软件)

    USB-Redirector-Technician 这个软件对于搞安卓刷机的人想必非常熟悉,淘宝破解版售价:38 一个的东西 除了远程刷机,用于映射一些小型设备是没问题的,只要网跟得上~ USB-Re ...

  8. [转] YUM 源优先级插件:Yum Priorities

    Linux 发行版比较多,同时还有很多个人或组织维护了某些特定用途的安装/升级源.Yum Priorities 插件可以用来强制保护源.它通过给各个源设定不同的优先级,使得系统管理员可以将某些源(比如 ...

  9. 2016级算法第六次上机-C.AlvinZH的学霸养成记II

    1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时cu ...

  10. 实验一 c++简单程序设计

    一.实验内容 1.ex 2_28 (1) 用if...else判断 #include<iostream> using namespace std; int main() { char i; ...