1 概念

initiator:发起通信请求的对象;

target:接收通信请求的对象;

producer:数据开始产生的对象;

consumer:数据最终流向的对象;

initiator和target的关系同producer和consumer的关系不是固定的,initiator作为数据的发起端,如果其使用的方法是put/try_put/can_put,则initiator也将作为producer;另外,如果其使用的方法是get/try_get/can_get/peek/try_peek/can_peek,则initiator也将作为consumer。

TLM通信步骤分为:

  • 定义TLM传输中的数据类型,定义request类和response 类。
  • 分别在各个层次的component中声明和创建TLM端口对象。
  • 在imp端口类中要实现需要提供给initiator的可调用方法。
  • 通过connect()函数完成端口之间的连接。

需要注意的是,必须在imp端口类中实现对应方法,否则端口即使连接也无法实现数据传输。

端口类型分为:

  • port: 经常作为initiator的发起端,initiator凭借port才可以访问target中的TLM方法;
  • export:作为initiator和target的中间层次;
  • imp:只能作为target接收request的末端。

端口的可通信方向:

  • port 可以连接 port 、 export 或 imp: export 可以连接 export 或 imp; imp 只能作为数据传送的终点, 无法扩展连接。
  • 多个 port 可以连接到同一个 export或imp; 但单个 port或export 无法连接多个imp 。这可以理解为多个initiator 可以对同一个 target 发起 request, 但是同一个initiator 无法连接多个target。

关于TLM概念的更多详细介绍可点击以下链接:

TLM通信https://blog.csdn.net/weixin_45680021/article/details/124348590

2 单向通信

单向通信 (unidirectional communication) 指的是从 initiator 到 target 的数据流向是单一方向的, 或者 initiator 和 target 只能扮演 producer 和 consumer 中的一个角色。

实例: 

1.首先comp1例化了两个port端口:
•     uvm_blocking_put_port #(itrans) bp_port; 
•     uvm_nonblocking_get_port #(otrans) nbg_port;

2.comp2作为target则相应例化了两个对应的imp端口:
•     uvm_blocking_put_imp #(itrans, comp2) bp_imp; 
•     uvm_nonblocking_get_imp #(otrans, comp2) nbg_imp;

3.env1环境将comp1与comp2连接之前, 需要在comp2中实现两个端口对应的方法:
•     task put(itrans t) 
•     function bit try_get (output otrans t)

4.env1环境将comp1与comp2连接之前, 需要在comp1中调用对应的方法:

•     this.bp_port.put(itr) 
•     this.nbg_port.try_get (otr)

5.接下来env1对两个组件的端口进行了连接, 这使得comp1在run phase可以通过自身端口间接调用comp2中定义的端口方法。

•     c1.bp_port.connect(c2.bp_imp); 
•     c1.nbg_port.connect(c2.nbg_imp);

更多端口介绍点击以下链接:

单向通信https://blog.csdn.net/weixin_45680021/article/details/124353341

3 双向通信

与单向通信相同的是,双向通信(bidirectional communication)的两端也分为initiator和target,但是数据流向在端对端之间是双向的。
双向通信中的两端同时扮演着producer和consumer的角色, 而initiator作为request发起方, 在发起request之后, 还会等待response返回。

双向端口按照通信握手方式可以分为: 

•    transport双向通信方式
•    master和slave双向通信方式

transport端口通过transport()方法, 可以在同一方法调用过程中完成REQ和RSP的发出和返回。
 master和slave的通信方式必须分别通过put、 get和peek的调用, 使用两个方法才可以完成一次握手通信。
master端口和slave端门的区别在于,当initiator作为master时,它会发起REQ送至target端, 而后再从target端获取RSP; 当initiator使用slave端口时,它会先从target端获取REQ, 而后将RSP送至target端。

实例: 

 transport双向通信方式

1.首先comp1例化了port端口:
•     uvm_blocking_transport_port #(itrans,otrans) bt_port;

2.comp2作为target则相应例化了两个对应的imp端口:
•     uvm_blocking_transport_imp #(itrans,otrans,comp2) bt_imp;

3.env1环境将comp1与comp2连接之前, 需要在comp2中实现两个端口对应的方法:
•     task transport(itrans req, output otrans rsp);

4.env1环境将comp1与comp2连接之前, 需要在comp1中调用对应的方法:

•     this.bt_port.transport(itr,otr) ;

5.接下来env1对两个组件的端口进行了连接, 这使得comp1在run phase可以通过自身端口间接调用comp2中定义的端口方法。

•     c1.bt_port.connect(c2.bt_imp); 
master双向通信方式

1.首先comp1例化了port端口:
•     uvm_blocking_master_port #(itrans,otrans) bm_port;

2.comp2作为target则相应例化了两个对应的imp端口:
•     uvm_blocking_master_imp #(itrans,otrans,comp2) bm_imp;

3.env1环境将comp1与comp2连接之前, 需要在comp2中实现两个端口对应的方法:
•     task put(itrans req);

•     task get(output otrans rsp);

4.env1环境将comp1与comp2连接之前, 需要在comp1中调用对应的方法:

•     this.bm_port.put(itr) 
•     this.bm_port.get (otr)

5.接下来env1对两个组件的端口进行了连接, 这使得comp1在run phase可以通过自身端口间接调用comp2中定义的端口方法。

•     c1.bm_port.connect(c2.bm_imp);

slave双向通信方式

1.首先comp1例化了port端口:
•     uvm_blocking_slave_port #(itrans,otrans) bs_port;

2.comp2作为target则相应例化了两个对应的imp端口:
•     uvm_blocking_slave_imp #(itrans,otrans,comp2) bs_imp;

3.env1环境将comp1与comp2连接之前, 需要在comp2中实现两个端口对应的方法:
•     task put(otrans rsp);

•     task get(output itrans req);

4.env1环境将comp1与comp2连接之前, 需要在comp1中调用对应的方法:

•     this.bs_port.put(otr) 
•     this.bs_port.get (itr)

5.接下来env1对两个组件的端口进行了连接, 这使得comp1在run phase可以通过自身端口间接调用comp2中定义的端口方法。

•     c1.bs_port.connect(c2.bs_imp);

从上面代码可以看出,双向端口处理类似于单向端口的是端口例化和连接, 不同的只是要求实现对应的双向传输任务: 

transport:

•     task transport(itrans req, output otrans rsp);

master:

•     task put(itrans req);

•     task get(output otrans rsp);

slave:

•     task put(otrans rsp);

•     task get(output itrans req);

更多端口介绍点击以下链接:

双向通信https://blog.csdn.net/weixin_45680021/article/details/124353341

3 多向通信

多向通信指的是, 如果initiator与target之间的相同TLM端口数目超过一个时的处理解决办法。

范式:

`uvm_blocking_put_imp_decl(SFX)

`uvm_nonblocking_put_imp_decl(SFX)

注意:该通信方法主要针对imp端口提出的,因为当有两个uvm_blocking_put_imp端口, 我们对于端口例化可以给不同名字, 连接也可以通过不同名字来索引, 但问题在于comp2中需要实现两个task put (itrans t), 又因为不同端口之间要求在imp端口侧实现专属方法, 这就造成了方法命名冲突, 即无法在comp2中定义两个同名的put任务。UVM通过端口宏声明方式来解决这一问题, 它解决问题的核心在于让不同端口对应不同名的任务, 这样便不会造成方法名的冲突。

实例: 

1.首先为避免target端口声明冲突,定义了两个宏;

•    `uvm_blocking_put_imp_decl(_pl);

•    `uvm_blocking_put_imp_decl(_p2);

2.在comp1例化了两个port端口:
•     uvm_blocking_put_port #(itrans) bp_port1; 
•     uvm_blocking_put_port #(itrans) bp_port2;

3.comp2作为target则相应例化了两个对应的imp端口:
•     uvm_blocking_put_imp_p1 #(itrans, comp2) bp_imp_p1; 
•     uvm_blocking_put_imp_p2 #(itrans, comp2) bp_imp_p2;

4.env1环境将comp1与comp2连接之前, 需要在comp2中实现两个端口对应的方法:
•     task put_p1(itrans t) ;
•     task put_p2(itrans t);

5.env1环境将comp1与comp2连接之前, 需要在comp1中调用对应的方法:

•     this.bp_port1.put(itr) 
•     this.bp_port2.put (itr)

6.接下来env1对两个组件的端口进行了连接, 这使得comp1在run phase可以通过自身端口间接调用comp2中定义的端口方法。

•     c1.bp_port1.connect(c2.bp_imp_p1); 
•     c1.bg_port2.connect(c2.bg_imp_p2);

注意:对于 comp1调用 put()方法, 它只需要选择 bp_port1 或 bp_port2, 而不需要更替 put()方法名, 即仍然按照 put()来调用而不是 put_pl()或 put_p2()。

总结:用户只需要在例化多个imp端口的组件中实现不同名称的方法,使其与对应imp类型名保持一致。而对于port端口一侧的组件,则不需关心调用的方法名称,因为该方法名并不会发生改变。所以通过这种方式可以防止通信方法名的冲突,从而解决多向通信的问题。

更多端口介绍点击以下链接:

多向通信https://blog.csdn.net/weixin_45680021/article/details/124353341

4 通信管道

利用通信管道可以解决以下问题:

1.对于仅仅存放数据的方法,不需要再去手动定义,通信管道已将这些方法固定在内部;

2.通信管道实现了一端连接多端

4.1 TLM_FIFO

uvm_tlm_fifo类是一个新组件, 它继承于uvm_component 类, 而且已经预先内置了多个端口以及实现了多个对应方法供用户使用。

uvm_tlm_fifo的功能类似于mailbox,不同的地方在于uvm_tlm_fifo提供了各种端口供用户使用 。推荐在initiator端例化put_port或者get_peek_port, 来匹配uvm_tim_fifo的端口类型。如果用户例化了其它类型的端口, uvm_tlm_fifo还提供put、get以及peek对应的端口:

4.2 Analysis port

Analysis port 的核心在于:

第一, 这是从一个 initiator 端到多个 target 端的方式;

第二, analysis port 采取的是 "push" 模式, 即从 initiator 端调用多个 target 端的 write()函数实现数据传输。

在 initiator 端调用wirte()函数时, 实际上它是通过循环的方式将所有连接的 target 端内置的 write()函数进行了调用。由于函数立即返回的特点, 无论连接多少个 target 端, initiator 端调用 write()函数总是可以立即返回的。这里稍微不同于之前单一端口函数调用的是,即使没有target 与之相连,调用 write() 函数时也不会发生错误。

4.3 Analysis TLM FIFO

由于 analysis 端口实现了一端到多端的 TLM 数据传输,一个新的数据缓存组件类uvm_tlm_analysis_fifo为用户提供了可以搭配 uvm_analysis_port 端口、 uvm_analysis_imp 端口和write()函数. uvm_tlm_analysis_fifo 类继承于 uvm_tlm_fifo, 这表明它本身具有面向单一 TLM 端口的数据缓存特性, 同时该类又有一个 uvm_analysis_imp 端口 analysis_ export 且实现了 write()函数.

4.4 Request&Response 通信管道

关于通信管道相关内容请点击以下链接:

通信管道https://blog.csdn.net/weixin_45680021/article/details/124353341

5 TLM2.0

更多关于TLM2.0的介绍请点击以下链接:

TLM2.0https://blog.csdn.net/weixin_45680021/article/details/124368966

UVM重点归纳(二)之TLM通信相关推荐

  1. uvm基础(2)TLM通信,看这一篇就够了

    tlm通信概述 tlm通信的步骤:1.分辨出initiator和target,producer和consumer. 2.在target中实现tlm通信方法. 3.在俩个对象中创建tlm端口. 4.在更 ...

  2. UVM重点归纳(一)

    1 factory 机制 1.1 利用工厂机制的一般实现步骤: 1.继承 范式: class comp_type/obj_type extends uvm_component/uvm_object; ...

  3. UVM_6:事务级建模TLM通信

    文章目录 前言 一.简单例子:driver-sequencer组件之间的通信 二.TLM通信 三.TLM通信步骤 四.TLM通信的分类 五.端口的使用 六.单向通信 七.双向通信 八.多向通信 1. ...

  4. UVM通信篇之一:TLM通信概论

    本文转自:http://www.eetop.cn/blog/html/28/1561828-5940098.html 在目前SoC设计的几大挑战当中,最令人关注的莫过于: 爆炸性增长的复杂度(然而被互 ...

  5. (13)UVM 史上最全TLM单向/双向/多向通信介绍

    UVM 史上最全TLM单向/双向/多向通信介绍 文章目录 UVM 史上最全TLM单向/双向/多向通信介绍 一.TLM单向通信 1.概述 2.类型 3.方法 4.单向通信例子 二.TLM双向通信 1.概 ...

  6. UVM中的TLM通信

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

  7. TLM通信 — UVM

    文章目录 简介 1.端口的使用 2.单向通信 3.双向通信 4.多向通信 5.通信管道 1. TLM_FIFO 2. Analysis Port 3. Analysis TLM FIFO 4. req ...

  8. UVM——TLM通信(1)

    目录 TLM的定义 通信的端口定义和所在的组件 单向通信 定义 通信流程 多向通信 定义 通信流程 通信管道 定义 通信流程 前言:基于<UVM实战>和路科讲解的TLM通信,总结一下 TL ...

  9. UVM入门与进阶学习笔11——TLM通信(3)

    目录 通信管道 TLM FIFO Analysis Port Analysis TLM FIFO Request & Response通信管道 通信管道 TLM通信的实现方式的共同点在于都是端 ...

最新文章

  1. 【最简洁】一句CSS3代码实现不规则自定义背景图拼接样式,多用于异形弹窗背景图
  2. 面试问了这两个问题,很多人的回答都自相矛盾
  3. 2021年春节联欢晚会第三次联排亮点多
  4. 【计算机视觉】OpenCV的最近邻开源库FLANN
  5. 那年的12月,那些悟与思2018-12-23
  6. bgp 建立邻居发送的报文_大型网络BGP之IBGP和EBGP邻居关系基础配置
  7. redis队列缓存 + mysql 批量入库 + php离线整合
  8. css实现web前端最美的loading加载动画!
  9. mysql分片库分页查询_Mysql分库分表
  10. ActiveMq工作笔记003---SpringBoot集成ActiveMq_随时更新
  11. rest_framework 权限功能
  12. 在Windows Embedded CE下进行Native C++开发,一次错误使用多线程的经验教训
  13. 使用说明 思迅收银系统_浅析思迅软件收银系统常见的功能主要有哪些?
  14. 四足机器人--嵌入式硬件设计
  15. 51单片机—LED小灯的点亮及其流水灯程序
  16. 一张图看懂企业经营,企业战略的本质,企业数字化转型 Road Map, 企业大脑的本质...
  17. kettle启动时报错:Maximum wait time of 10 seconds exceed while acquiring lock
  18. 2018年六级第三套自行车翻译
  19. JS在VS coder界面写promt和alter语句无法在浏览器页面显示
  20. LFS学习系列3 — 前言

热门文章

  1. DRM加密技术是怎么一回事
  2. 知网Java开发面试题_CNKI(同方知网)+社招+java
  3. Springboot学习笔记 | 尚硅谷雷神
  4. python读取pdf文档书签 bookmark_pdf根据目录生成书签
  5. 自学PHP笔记(二)PHP数据类型
  6. VR实战案例 | HTC Vive射箭游戏-晴天-专题视频课程
  7. C语言程序设计用if,C语言程序设计 1. if语句的运用 案例-if条件语句.docx
  8. 15. Examples【示例】
  9. 如何靠网络快速打造品牌
  10. Unity3D脚本:Unity制作连连看脚本