摘自: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. centos6.6 下安装mysql5.7

    背景 没啥好说的,就是需要搭建自己的测试数据库跟研发的数据隔离开来,需要怼mysql 这个方法只适合mysql5.7 # mysql5.6的有差异 步骤 1. 确认线上mysql的版本 SELECT ...

  2. myeclipse过期以后提示过期以后怎么办?!

    昨天电脑上装的myeclipse到期了,不能进到工作空间里边,只有激活和退出选项,在网上百度了一下,有很多破解工具, 1.刚开始直接使用工具破解,没有成功,总是提示要么激活,要么退出 2.继续想办法, ...

  3. EF查询记录

    public void TestMethod1() { , Ids = , Ids = "4,5,6" } }; , , , , , , , }; var query = quer ...

  4. C#基础笔记(第十五天)

    1.Directory//File 文件 Path 路径 FileStream StreamReader StreamWriter 流 Directory 文件夹 目录 //创建文件夹 Directo ...

  5. sgi stl内存池实现------源码加翻译

    class __default_alloc_template { enum { unit = 8 };//分配单位 后面直接用8代替 enum { max_bytes = 128 };//最大分配字节 ...

  6. “全栈2019”Java第八十五章:实现接口中的嵌套接口

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. 任意模数NTT和FFT的玄学优化学习笔记

    本来一直都是写\(7\)次的\(MTT\)的--然后被\(shadowice\)巨巨调教了一通之后只好去学一下\(4\)次的了-- 简单来说就是我们现在需要处理一类模数不为\(NTT\)模数的情况 这 ...

  8. iOS关于代码风格问题

    cocoapods管理第三方库,详见cocoapods安装及使用 OC代码风格需要规范,所有第三方依赖需要用cocoapods管理.代码风格需要: 1. pod 'CodeFormatter', :g ...

  9. Spring Boot入门教程(1)

    Spring Boot入门教程(1) 本文将使用Spring Boot一步步搭建一个简单的Web项目来帮助你快速上手. 将要用到的工具 JDK 8 IntelliJ IDEA(Ultimate Edi ...

  10. HDU-1160-FatMouse's Speed(线性DP,LIS)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...