摘自: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. apache ap 并发测试工具

    可以使用 apache httpd 软件包里的 ab.exe 简单的做些网站的性能测试, ab.exe 是一个命令工具,所以不能双击运行, 在 cmd 下运行: ab.exe -n 1000 -c 5 ...

  2. ASP.NET 常用的字符串加密

    字符串常用的加密有三种 1.MD5加密,这个常用于密码,单向加密,不可解密,有些在线解密的可以解大部份,用代码不能实现,如果不想让人解密,加密后随便截取一段就好了: 2.Base64位加密,通常加密后 ...

  3. C++ windows进程间通信

    最近一直在找共享内存同步的操作,恰好这篇文章有讲解.本文转载:https://blog.csdn.net/bing_bing_bing_/article/details/82875302 方便记录,c ...

  4. 【ocp-12c】最新Oracle OCP-071考试题库(40题)

    40.(8-7) choose two Which two statements are true regarding views? (Choose two.) A) A simple view in ...

  5. JavaScript多个h5播放器video,点击一个播放其他暂停

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. flask源码解析之DispatcherMiddleware

    DispatcherMiddleware作用 实现多app的应用,完成路由分发的功能 如何使用 from werkzeug.wsgi import DispatcherMiddleware from ...

  7. 代码审计就该这么来3 beescms getshell

    本文作者:i春秋作家——索马里的海贼 前言上一回(http://bbs.ichunqiu.com/thread-13714-1-1.html)说到快速漏洞挖掘中的几个重点关注对象,命令执行,文件操作, ...

  8. logstash同步mongodb数据到elasticsearch

    一.安装logstash 二.安装mongodb插件 cd D:\Software\ELK5.5.0\logstash-5.5.0\bin logstash-plugin install logsta ...

  9. Java 文件本地上传、下载和预览的实现

    以下方法为通用版本 实测图片和pdf 都没有问题 上传方法需要前端配合post请求 ,下载前端用a标签就可以,预览 前端使用ifrme标签   ,就可以实现基本功能... 1.文件本地上传 publi ...

  10. JavaScript基础总纲

    如果前人种好了树那我们干嘛不去享受阴凉,然后花费时间去为大树的成长进一份力. 我发现一个站点写的很全面写很系统,我总结主要分为一些几个模块: 一,JavaScript 教程(基础) 二,JavaScr ...