UVM 史上最全TLM单向/双向/多向通信介绍

文章目录

  • UVM 史上最全TLM单向/双向/多向通信介绍
    • 一、TLM单向通信
      • 1.概述
      • 2.类型
      • 3.方法
      • 4.单向通信例子
    • 二、TLM双向通信
      • 1.概述
      • 2.分类
      • 3.双向通信例子
    • 三、TLM多向通信
      • 1.概述
      • 2.端口宏声明
      • 3.实现步骤
      • 4.多向通信例子
  • 关注作者

一、TLM单向通信

1.概述

单向通信(unidirectional communiction)指的是从initiator到target之间的数据流向是单一方向的,或者说initiator和target只能扮演producer和consumer中的一个角色。在UVM中,单一数据流向的TLM端口有很多类型:

uvm_blocking_put_PORT
uvm_nonblocking_put_PORT
uvm_put_PORT
uvm_blocking_get_PORT
uvm_nonblocking_get_PORT
uvm_get_PORT
uvm_blocking_peek_PORT
uvm_nonblocking_peek_PORT
uvm_peek_PORT
uvm_blocking_get_peek_PORT
uvm_nonblocking_get_peek_PORT
uvm_get_peek_PORT

2.类型

这里的PORT代表了三种端口名:port、export和imp。按照UVM端口名的命名规则,指出了通信的两个要素:

  1. 是不是阻塞的方式(即可以等待延时)
  2. 何种通信方法

3.方法

  • 阻塞传输方式将blocking前缀作为函数名的一部分,而非阻塞方式则名为nonblocking。阻塞端口的方法类型为task,这保证了可以实现事件等待和延时;非阻塞端口的方式类型为function,这确保了方法调用可以立即返回。
  • 我们才方法名也可以发现,例如uvm_blocking_put_PORT提供的方法task put()会在数据传送完后返回,uvm_non_blocking_put_PORT对应的两个函数try_put()和can_put()是立刻返回的。
  • uvm_put_PORT则分别提供了blocking和nonblocking的方法,这为通讯方式提供了更多选择。blocking阻塞传输的方法包含:
    1.put():initiator先生成数据Tt,同时将该数据传送至target。
    2.get():initiator从target获取数据Tt,而target中的该数据Tt则应消耗。
    3.peek():initiator从target获取数据Tt,而target中的数据Tt还应保留。
  • 与上述三种任务对应的nonblocking非阻塞方法分别是:
    1.try_put()
    2.can_put()
    3.try_get()
    4.can_get()
    5.try_peek()
    6.can_peek()
  • 这六个非阻塞函数与对应阻塞任务的区别在于,它们必须立即返回,如果try_xxx函数可以发送或者获取数据,那么函数应该返回1,如果执行失败则应该返回0。
  • 可以通过can_xxx函数先试探target是否可以接收数据,如果可以,再通过try_xxx函数发送,提高数据发送的成功率。

4.单向通信例子

class itrans extends uvm_transaction; int id;int data; ...
endclass
class otrans extends uvm_transaction; int id; int data;
...
endclass
class compl extends uvm_component;uvm_blocking_put_port #(itrans) bp_port;uvm_nonblocking_get_port #(otrans) nbg_port;`uvm_component_utils(comp1)
...task run_phase(uvm_phase phase);itrans itr;otrans otr;int trans_num=2;forkbeginfor(int i=0;i<trans_num;i++)beginitr=new("itr",this);itr.id=i;itr.data='h10+i;this.bp_port.put(itr);`uvm_info("PUT",$sformatf("put itrans id:'h%0x, data:'h%0x",itr.id, itr.data), UVM_LOW)endendbeginfor(int j=0;j<trans_num;j++)beginforever beginif(this.nbg_port.try_get(otr)==1)break;else #1ns;end`uvm_info("TRYGET", $sformatf("get otrans id:'h%0x,data:'h%0x",otr.id,otr.data),UVM_LOW)endendjoinclass comp2 extends uvm_component;uvm_blocking_put_imp #(itrans, comp2) bp_imp;uvm_nonblocking_get_imp #(otrans, comp2) nbg_imp;itrans itr_q[$];`uvm_component_utils(comp2)...task put(itrans t);itr_q.push_back(t)endtaskfunction bit try_get(output otrans t);itrans i;if(itr_q.size()!=0)begini= itr_q.pop_front();t=new("t",this);t.id=i.id;t.data=i.data<<8;return l;endelse return 0;endfunctionfunction bit can_get();if(itr_q.size()!=0)return 1;else return 0;endfunction
endclass
class envl extends uvm_env;compl cl;comp2 c2;`uvm_component_utils(envl)...function void build_phase(uvm_phase phase);super.build_phase(phase);cl =comp1::type_id::create("cl",this);c2 =comp2::type_id::create("c2",this);endfunction:build_phase function void connect_phase(uvm_phase phase);super.connect_phase(phase);cl.bp_port.connect(c2.bp_imp);cl.nbg_port.connect(c2.nbg_imp);endfunction:connect_phase
endclass


代码解析
首先comp1例化了两个port端口:

  • uvm_blocking_put_port#(itrans)bp_port;
  • uvm_nonblocking_get_port#(otrans)nbg_port;

comp2作为target则相应例化了两个对应的imp端口:

  • uvm_blocking_put_imp#(itrans,comp2)bp_port;
  • uvm_nonblocking_get_imp#(otrans,comp2)nbg_imp;

env1环境将comp1与comp2连接之前,需要在comp2中实现两个端口对应的方法:

  • task put(itrans t)
  • function bit try_get(output otrans t)
  • function bit can_get();

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

因此在调用端口方法之前的几个步骤是必不可少的:

  • 定义端口
  • 实现对应方法
  • 在上层将端口进行连接

二、TLM双向通信

1.概述

  • 与单向通信相同的是,双向通信(bidirectional communication)的两端也分为initiator和target,但是数据流向在端对端之间是双向的。
  • 双向通信中的两端同时扮演着producer和consumer的角色,而initiator作为request发起方,在发起request之后,还会等待response返回。
  • UVM双向端口分为以下类型
uvm_blocking_transport_PORT
uvm_nonblocking_transport_PORT
uvm_transport_PORT
uvm_blocking_master_PORT
uvm_nonblocking_master_PORT
uvm_master_PORT
uvm_blocking_slave_PORT
uvm_nonblocking_slave_PORT
uvm_slave_PORT

2.分类

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

  • transport双向通信方式
    transport端口通过transport()方法,可以在同一方法调用过程中完成REQ和RSP的发出和返回。
  • master和slave双向通信方式
    master和slave的通信方式必须分别通过put、get和peek的调用,使用两个方法才可以完成一次握手通信。
    master端口和slave端口的区别在于,当initiator作为master时,它会发起REQ送至target端(put()),而后再从target端获取RSP(get());当initiator使用slave端口时,它会先从target端获取REQ(get()),而后将RSP送至target端(put())。
    对于master端口或者slave端口的实现方式,类似于之前介绍的单向通信方式,只是imp端口所在的组件需要实现的方法更多了。

3.双向通信例子

class comp1 extends uvm_component;uvm_blocking_transport_port#(itrans,otrans)bt_port;`uvm_component_utils(comp1)...task run_phase(uvm_phase phase);itrans itr;otrans otr;int trans_num=2;for(int i=0;i<trans_num;i++)beginitr=new("itr",this);itr.id=i;itr.data='h10+i;this.bt_port_transport(itr,otr);`uvm_info("TRSPT",$sformatf("put itrans id:'h%0x, data:'h%0x",,get otrans id: 'h%0x,data:'h%0x",itr.id, itr.data,otr.id,otr.data), UVM_LOW)endendtask
endclass
class comp2 extends uvm_component;uvm_blocking_transport_imp #(itrans, otrans,comp2) bt_imp;`uvm_component_utils(comp2)...task transport(itrans req,output otrans rsp);rsp=new("rsp",this);rsp.id=req.id;rsp.data=req.data<<8;endtask
endclass
class env1 extends uvm_env;


双向端口处理类似于单向端口的是端口例化和连接,不同的只是要求实现对应的双向传输任务。
task transport(itrans req,output otrans rsp)

三、TLM多向通信

1.概述

  • 多向通信(multi_directional communication)这个概念听起来容易让读者产生歧义,因为这种方式服务的仍然是两个组件之间的通信,而不是多个组件之间的通信,而不是多个组件之间的通信,毕竟多个组件的通信仍然可以由基础的两个组件的通信方式来构建。
  • 多向通信指的是,如哦initiator与target之间的相同的TLM端口数目超过一时的处理解决办法。
  • comp1有两个uvm_blocking_put_port,而comp2有两个uvm_blocking_put_imp端口,我们对于端口例化可以给不同名字,连接也可以通过不同名字来索引,但问题在于comp2中需要实现两个task put(itrans t),又因为不同端口之间要求在imp端口一侧实现专属方法,这就造成了命名冲突,即无法在comp2中定义两个同名的put任务。

2.端口宏声明

UVM通过端口宏声明方式来解决这一问题,它解决问题的核心在于让不同端口对应不同名的任务,这样便不会造成方法名的冲突。UVM为解决多向通信问题的宏按照端口名的命名方式分为:

3.实现步骤

当一个组件的两个端口通过相同方法(譬如task put())向另外一个组件传输数据时,就需要使用上面的宏,分别声明两个不同的imp类型,完整的实现步骤包括:

  • 选择正确的imp宏来定义不同imp端口类型,而宏的参数SFX(后缀名)也会转换为相应的imp端口类型名。
  • 在imp所例化的组件中,分别实现不同的put_SFX方法。
  • 在port所例化的组件中,不需要对目标imp端口类型做区分,例如comp1中的bp_port1和bp_port2为相同的端口类型。
  • 对于comp1调用put()方法,它只需要选择bp_port1或者bp_port2,而不需要更替put()方法名,即仍然按照put()来调用而不是put_p1()或者put_p2()。
  • 在上层环境应该连接comp1和comp2的TLM端口。
  • 用户只需要在例化多个imp端口的组件中实现不同名称的方法,使其与对应imp类型名保持一致。
  • 而对于port端口一侧的组件,则不需要关心调用的方法名称,因为该方法名并不会发生改变。
  • 所以通过这种方式可以防止通信方法名的冲突,从而解决多向通信的问题。

4.多向通信例子

`uvm_blocking_put_imp_decl(_p1)
`uvm_blocking_put_imp_decl(_p2)
class comp1 extends uvm_component;uvm_blocking_put_port#(itrans) bp_port1;uvm_blocking_put_port#(itrans) bp_port2;....
endclassclass comp2 extends uvm_component;uvm_blocking_put_imp_p1#(itrans,comp2) bp_imp_p1;uvm_blocking_put_imp_p2#(itrans,comp2) bp_imp_p2;...
endclassclass env1 extends uvm__env;comp1 c1;comp2 c2;`uvm_component_utils(env1)function void build_phase(uvm_phase phase);...endfunctionfunction void connect_phase(uvm_phase phase);c1.bp_port1.connect(c2.bp_imp_p1);c1.bp_port2.connect(c2.bp_imp_p2);endfunction:connect_phase
endclass

关注作者

  • 自述
    作者是一位中科大数字设计专业的研究生,水平有限,如有错误,请大家指正,想要与大家一同进步。
  • 经历
    曾获得国家奖学金,“高教社杯”数学建模国家二等奖等
  • 陆续更新:
    1.与UVM验证相关的system verilog后续内容;
    2.与verilog数字设计相关的一些基础模块设计,例如FIFO,UART,I2C等的书写。
    3.保研与竞赛经历等
  • 微信公众号
    欢迎大家关注公众号“数字IC小白的日常修炼”,期待与大家一同仗剑遨游数字IC世界。

(13)UVM 史上最全TLM单向/双向/多向通信介绍相关推荐

  1. (14)UVM 史上最全通信管道介绍

    UVM通信管道 文章目录 UVM通信管道 一.前言 二.TLM FIFO 三.Analysis Port 四.Analysis TLM FIFO 五.Request & Response 通信 ...

  2. if null 锁 java_史上最全 Java 中各种锁的介绍

    什么是锁 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制.锁旨在强制实施互斥排他.并发控制策略. 锁通常需要硬件支持才能有效实施.这 ...

  3. 史上最全的分词算法与工具介绍

    分词(word tokenization),也叫切词,即通过某种方式将句子中的各个词语识别并分离开来,使得文本从"字序列"的表示升级为"词序列"表示.分词技术不 ...

  4. abb工业机器人指令lf怎么用_史上最全的ABB工业机器人的指令介绍

    AccSet-降低加速度 ActEventBuffer - 事件缓冲启用 ActUnit - 启用机械单元 Add-增加数值 AliasIO - 确定I/O 信号以及别名 AliasIOReset-重 ...

  5. ElasticSearch集成SpringData史上最全查询教程

    ElasticSearch集成SpringData史上最全查询教程 1.简单介绍 springboot 使用springdata操作es,ElasticsearchRepository使用QueryB ...

  6. css中float详解,CSS浮动属性Float详解?史上最全Float详解

    我们在学习css样式的时候,都知道css是盒概念,并且每一个盒子都是一个元素,下面我们就对CSS浮动属性Float进行详解,让你彻底了解Float. 一:什么是Float浮动? Float浮动是css ...

  7. 史上最全阿里 Java 面试题总结及答案

    史上最全阿里 Java 面试题总结及答案 qq_35151346 于 2019-08-06 13:26:53 发布 33740 收藏 817 分类专栏: 面试题 文章标签: 阿里巴巴 面试题 答案 j ...

  8. Hashmap 原理、源码、面试题(史上最全)

    文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :<尼恩Java面试宝典>持续更新+ 史上最全 + 面 ...

  9. 2023史上最全Java面试题【完整版】跳槽必备,看完轻松收撕面试官

    ✨作者简介:杨 戬,博客专家.github开源作者 ✨多年工作总结:Java学习路线总结,小白逆袭Java技术总监 ✨技术交流:定期更新Java硬核干货,不定期送书活动.助你实现技术飞跃 ✨关注公众号 ...

最新文章

  1. Java基础-重写方法
  2. python流程控制语法_005 Python语法之流程控制
  3. 用 Freemarker 生成 word 文档
  4. VC程序调试技术,一些工具上和具体的问题,包括内存检测
  5. python列表写入csv文件_将多个列表写入csv。Python中的文件
  6. GPU Gems1 - 12 全方位的阴影映射
  7. 【转载保存】匿名内部类中this的使用
  8. input 没显示 html,html - 为什么我的input type =“submit”没有显示?
  9. Dxg——C# 开发笔记整理分类合集【所有的相关记录,都整理在此】
  10. Uber和Lyft推个人验证PIN码功能降接送混乱
  11. 生成条形码(jsbarcode、vue-barcode)
  12. 计算机上什么键有存储,电脑保存的快捷键是什么_电脑知识
  13. while循环语法结构
  14. 最健康的程序员作息表
  15. 循环报错: 远程主机强迫关闭了一个现有的连接
  16. js 创建标签 追加标签
  17. Gearbox变速器
  18. 使用biblatex时如何改变指定参考文献的颜色
  19. 打印从1到最大的n位数——《剑指offer》
  20. 为什么65535是极值

热门文章

  1. 计算机毕业设计(附源码)python学校实验室设备管理系统
  2. 简单的学籍管理系统c语言,c语言学生学籍管理系统—精简版.pdf
  3. 数据库——实验八 触发器实验
  4. Openjudge:正常血压
  5. 已知华氏求摄氏C语言,c语言:根据华氏温度求摄氏温度,并分析错误
  6. ucos OS_ENTER_CRITICAL .
  7. 华为P20 如时升Android 9.0,华为P20系列升级EMUI9.0之后简直太流畅太完美!
  8. wrl文件转换成obj文件
  9. 单链表的应用---通讯录设计(数据结构课设)
  10. 串口服务器中文使用文档,MOXA串口服务器中文使用文档