在简单的测试平台里,component之间通过变量或者config_db机制通信是可行的,但是如果在复杂测试平台中依然使用这种耦合性很强的方式通信的话,就不太行了。因此,UVM提供了TLM这样的概念。接下来将会从需求出发,逐步引入port、export、imp、analysis端口、uvm_analysis_imp_decl宏以及FIFO等。

1 典型UVM验证平台

2 一对一如何通信(一般方法)

说明:这里以monitor和scoreboard之间的通信为例

  • 方法一使用全局变量:在monitor里对此全局变量进行赋值, 在scoreboard里监测此全局变量值的改变

    • 问题:所有模块都可以修改全局变量,合作中他人误修改可能导致致命bug
  • 方法二A中pulic变量+B对模块A的引用:scoreboard中使用public类型的变量,然后monitor中使用指向scoreboard的指针对该变量进行赋值
    • 问题:monitor可以修改scoreboard中所有public类型变量
  • 方法三config机制(类似于在指定模块作用域构建了全局变量): 在base_test中实例化一个config_object,并将其指针通过config_db传递给scoreboard和monitor,然后两个模块就可以对该config_object中变量进行操作
    • 问题1:需要引入一个专门的config_object类
    • 问题2:一定要有base_test(父模块)这个第三方的参与,这样就不能保证某一个从base_test派生而来的类会不会改变这个config_object类中某些变量的值

现有机制更多通信问题

  • 通信需要考虑阻塞和非阻塞的处理方式
  • 如果scoreboard主动要求向monitor请求数据, 这样的行为方式使用systemverilog搭建会非常复杂

3 一对一如何通信(引入TLM)

3.1 新概念

  • TLM:是Transaction Level Modeling( 事务级建模) 的缩写,是将某一特定功能的一组信息封装在一起成为一个类,通过这个类(即事务)进行通信。
  • 三个端口:PORT(发起者)、EXPORT(接收者)、IMP(执行者)
  • 端口方法:put/get/transport/peek/get_peek

3.2 使用举例

说明:以blocking_put系列端口,PORT>EXPORT>IMP的连接举例说明

  • A|PORT发起端口操作put:task A::main_phase中A_port.put(tr);
  • 建立A|PORT和B|EXPORT的连接:AB的顶层模块my_env::connect_phase中:A_inst.A_port.connect(B_inst.B_export);
  • 建立B|EXPORT和B|IMP的连接:B::connect_phase中:B_export.connect(B_imp);
  • 建立B|IMP和B中操作put的连接:B模块定义中:uvm_blocking_put_imp#(my_transaction, B) B_imp;
  • B中操作put的实现:function void B::put(my_transaction tr);

注意:EXPORT可以省略,即 PORT直接连接到IMP

4 一对多如何通信(引入analysis端口)

4.1 使用举例

  1. A|analysis_port发起端口操作write:task A::main_phase中A_ap.write(tr);
  2. 建立A|analysis_port和(B或C)|analysis_imp,的连接:A(B或C)的顶层模块my_env::connect_phase中
    A_inst.A_ap.connect(B_inst.B_imp);
    A_inst.A_ap.connect(C_inst.C_imp);
  3. 建立(B或C)|analysis_imp和(B或C)中操作write的连接:(B或C)模块定义中:
    uvm_analysis_imp#(my_transaction, B) B_imp;或
    uvm_analysis_imp#(my_transaction, C) C_imp;
  4. (B或C)中操作write的实现
    function void B::write
    function void C::write

5 多IMP的模块的通信问题

5.1 问题描述

一个component(my_scoreboard)内有多个IMP时,依据前面知识,component(my_scoreboard)中只能有一个write方法,这如何处理两个imp(来自输出监视monitor 和 来自参考模型model)

5.2 解决方法

方法一:使用宏uvm_analysis_imp_decl

通过宏uvm_analysis_imp_decl,在component(my_scoreboard)中添加不同的后缀以区分两个imp的处理逻辑。具体实现如下:

  1. 通过宏uvm_analysis_imp_decl声明两个后缀_monitor和_model
    uvm_analysis_imp_decl(**_monitor**)<br />uvm_analysis_imp_decl(_model)
  2. 使用带后缀的analysis_imp端口类声明两个analysis_imp端口
    uvm_analysis_imp**_monitor**#(my_transaction, my_scoreboard) monitor_imp;
    uvm_analysis_imp**_model**#(my_transaction, my_scoreboard) model_imp;
  3. 使用带后缀的write方法实现analysis_imp对信号的处理逻辑
    extern function void write**_monitor**(my_transaction tr);
    extern function void write**_model**(my_transaction tr);
  4. 宏uvm_analysis_imp_decl的特性会让 相同后缀的 analysis_imp端口 和 write函数 对应上
    function void my_scoreboard::write_model(my_transaction tr);
    function void my_scoreboard::write_monitor(my_transaction tr);

方法二:使用FIFO通信

将imp的实现逻辑放在FIFO中,而component(my_scoreboard)作为PORT端,主动请求get到FIFO中的数据,关键代码如下:

// my_scoreboard类中
uvm_blocking_get_port #(my_transaction) exp_port;
uvm_blocking_get_port #(my_transaction) act_port;
// task my_scoreboard::main_phase中
exp_port.get(get_expect); // 获取的数据存到get_expect中
act_port.get(get_actual); // 获取的数据存到get_actual中// my_env类中
uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;
uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;
uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;
// function void my_env::connect_phase中
i_agt.ap.connect(agt_mdl_fifo.analysis_export);
mdl.port.connect(agt_mdl_fifo.blocking_get_export);
mdl.ap.connect(mdl_scb_fifo.analysis_export);
scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);
o_agt.ap.connect(agt_scb_fifo.analysis_export);
scb.act_port.connect(agt_scb_fifo.blocking_get_export);

注意:FIFO中的analysis_export和blocking_get_export虽然名字中有关键字export, 但是其类型却是IMP

5.3 用FIFO还是用IMP

个人推荐使用FIFO,尤其是对于使用端口数组的情况。因为ap与imp直接相连不能使用for循环(write函数需要一个一个写,没法用数组),会导致代码量增加,理解困难。

6 参考资料

UVM实战(卷一) 张强 编著 机械工业出版社


如需了解更多相关内容,欢迎关注“多读点书”,让我们一起阅读,一起成长。

UVM中component之间如何通信相关推荐

  1. 《UVM实战》学习笔记——第四章 UVM中的TLM1.0通信

    文章目录 前言 一.TLM1.0 1.TLM的定义 2.数据流:数据流动的方向 3.控制流:动作发起者initiator.动作接收者target 4.各种端口的连接 5.transport 6.non ...

  2. Vue中父子之间的通信

    在学习vue中,往往会碰到父子组件之间的通信问题,用一张图来简单解释下父子之间如何通信 由图可以知道 父组件传递参数给子组件 子组件通过props接收参数 父子通信 代码演示: <!DOCTYP ...

  3. Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息...

    先看简单示例:点击按钮,2s之后,TextView改变内容. package cn.lixyz.handlertest;import android.app.Activity; import andr ...

  4. 从Android中Activity之间的通信说开来

    引言 最近两个星期在研究android的应用开发,学习了android应用开发的基础知识,基本控件,基本布局,基本动画效果,数据存储,http访问internet等等基础知识. android中有一个 ...

  5. 使用 Rxjs 解决 Angular Component 之间的通信问题

    本文讨论如果两个 Angular Component 彼此不知道对方的存在,并且也没有共享的父子 Component 时,如何进行通信. 在包括 Angular 在内的许多前端框架中,当我们将应用程序 ...

  6. java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...

    之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...

  7. QT中使用C++ socket通信,socket通信原理三次握手和四次握手详解、客户端与服务端实例详解

    对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP? 2.         Soc ...

  8. UVM中的TLM通信

    UVM中的TLM通信 1.TLM简介 TLM:Transaction Level Modeling(事务级建模),它是一个独立于语言的一个标准,常用于系统建模,加速软硬件协同开发.在芯片开发中,常配合 ...

  9. Vue中父子及非父子组件之间的通信方法

    Vue中父子及非父子组件之间的通信方法 父子组件之间的通信方法 父级->子级通信 (依赖单向数据绑定+props实现) Vue.component('Father', { //注册了含有data ...

最新文章

  1. MySQL Proxy 读写分离(实战总结)
  2. Docker渐入佳境
  3. 1.2 学习笔记之数据类型
  4. Leaflet中使用NavBar插件实现导航(前进后退)效果
  5. 业务总结001:优惠券与礼包活动
  6. objective-c中的static
  7. LINUX 下mysql主从安装与同步
  8. linux php pdo dblib,PDO_DBLIB (MSSQL) on Ubuntu Server
  9. 多重背包单调队列优化思路_单调队列优化多重背包问题
  10. Atitit.mvc的趋势与未来attilax总结
  11. 可以测试流放之路伤害的软件,流放之路DPS面板计算方式_流放之路怎么看自己的伤害_52PK...
  12. AutoCAD2000软件学习心得
  13. 人类自然语音频率范围
  14. win10计算机不分区,win10有必要分区吗
  15. 细菌感染和抗生素使用
  16. python 压缩 解压文件
  17. HBase进化之从NoSQL到NewSQL,凤凰涅槃成就Phoenix
  18. 改良型新药之详细分类
  19. 从十亿光年到0.1飞米
  20. 国内MEMS企业、研究所以及科研院校

热门文章

  1. sql定义表时,int(10)是什么意思?
  2. win10 nginx部署静态资源服务器和HTML
  3. matlab 罗德里格斯变换,修正罗德里格斯参数
  4. 基于Mybatis-Plus的多租户架构下的数据隔离解决方案
  5. Java Script如何实现创建一个按钮
  6. jdk与tomcat等版本相互适配要求
  7. 用NT52的boot.ini引导NT60启动Windows7
  8. Magisk 保留root升级系统(亲测小米)
  9. 宽带不能上传发文件_为啥4M的宽带为啥下载速度只有300多KB?
  10. 图片与Base64数据转换存储