UVM-TLM通信机制(四)
UVM-TLM通信机制
- 一、两对象与三端口
- 1.1.两个通信对象:initiator、target
- 1.2.三个通信端口:port、export、imp
- 二、一对一传输
- 2.1.单向传输——put( )和get( )操作传输
- 2.2.transport( )操作传输
- 2.3.跨层次传输——uvm_analysis_port
- 三、一对多传输
- 3.1.fifo模式
- 3.2.分析端口——Analysis port(一对多传输、最常用)
TLM(transaction level modeling)是一个基于事务(transaction)的通信方式,通常在高抽象级的语言中被引用作为模块之间的通讯方式,例如SystemC或者UVM。TLM通信需要两个通信的对象,这两个对象分别称之为initiator和target。
一、两对象与三端口
1.1.两个通信对象:initiator、target
- initiator:通信请求的发起方,属于initiator;
- target : 通信请求的响应方,谁就属于target;
注意:通信发起方并不代表了transaction的流向起点,即不一定数据是从initiator流向target,也可能是从target流向了initiator。因此,按照transaction的流向,我们又可以将两个对象分为producer和consumer。区分它们的方法:
- producer:生产数据方,即为producer;
- consumer:接收数据方,即为consumer;
1.2.三个通信端口:port、export、imp
通信端口按照类型可以划分为三种:
- port:通信请求方initiator的发起端,initiator凭借port端口才可以访问target。
- export:作为initiator和target中间层次的端口。
- imp:只能作为target接收请求的响应端,它无法作为中间层次的端口,所以imp的连接无法再次延伸。
端口优先级:port > export > imp, 使用connect()建立连接关系时,只有优先级高的才能调用connect()做连接,即port可以连接port、export或者imp;export可以连接export或者imp;imp只能作为数据传送的重点,无法扩展连接。三种端口非是uvm_component的子类,应该使用new()函数在build_phase中创建。(注意:不能用create创建,端口不属于UVM树的一部分)。
二、一对一传输
按通信传输的方向可以分为单向(unidirection)和双向(bidirection)。
需要说明的是,不论是单向传输还是双向传输都有阻塞和非阻塞之分。下面以阻塞传输为中心。
- 单向传输:由initiator发起request transaction,数据有生产方producer发送到数据接收方consumer。
- 双向传输:由initiator发起request transaction,传送至target;而target在消化了request transaction后,也会发起response transaction,继而返回给initiator。数据的流向是双向的。
- 所有常用的一对一Port类型的总结:
2.1.单向传输——put( )和get( )操作传输
2.1.1. Put( )型操作传输
- 单向通信中,port和export端口的参数只有一个;imp端口,参数有两个,第一个是传递的item类,第二个是实现该端口的component;
- 阻塞的传输方式通过blocking的前缀来作为函数名的一部分,而非阻塞的方式则名为nonblocking。
- 端口的实例化 使用new()函数在build_phase中创建
- 阻塞的方法类型为task,这保证了可以实现等待事件和延时;非阻塞的方法类型为function,这确保了方法调用可以立刻返回。
- 发起者的动作实现,最终会落到终点IMP所在的component中,因此必须 在imp所在的component中定义名字为put/get/transport的函数或任务,完成最终的数据传输操作。
class transaction extends uvm_transaction; //传输数据包int id;int data;...
endclassclass producer extends uvm_component; //数据生产方producer...uvm_blocking_put_port#(transaction) put_port; //定义端口function void build_phase(uvm_phase phase);put_port = new("put_port",this); //创建实例化端口endfunctiontask run_phase(uvm_phase phase); put_port.put(tr); //通过数据接收方consumer提供的任务put()处理数据,然后通过TLM传输数据过去endtask
endclassclass consumer extends uvm_component; //数据接收方consumer...uvm_blocking_put_imp#(transaction, consumer) put_imp; //定义端口function void build_phase(uvm_phase phase);put_imp = new("put_imp",this); //创建实例化端口endfunctionvirtual task put(transaction tr); //数据生产方producer会调用接收方consumer定义的put()任务process(tr); //通过数据接收方consumer提供的任务put()处理数据endtask
endclassclass environment extends uvm_env; //环境层...producer p; //数据生产方consumer c; //数据接收方...virtual function void connect_phase(uvm_phase phase);p.put_port.connect(c.put_imp); //建立连接endfunction
endclass
1)、上述代码分别在producer和consumer中声明并例化了两个端口实例:
uvm_blocking_put_port #(transaction) put_port;
uvm_blocking_put_imp #(transaction,consumer) put_imp;//第一个是传递的item类,第二个是实现该端口的component**;
2)、在environment环境对producer与consumer进行连接之前,需要在consumer中实现两个端口对应的方法
virtual task put( transaction tr ); //阻塞端口需要定义为任务task
3)、最后在environment中对两个组件之间的端口进行了连接,这使得producer的run phase中可以通过自身的两个端口间接调用consumer中的方法。需要注意的是,在调用方法之前的几个步骤是必不可少的:
– 定义端口
– 实现对应方法
– 在上层将端口进行连接
2.1.2.Get( )型操作传输
数据请求由consumer主动发起,通过调用producer中的get函数建立起连接。红色为port端口,绿色为imp端口。事务传输方向为箭头指向方向。
class transaction extends uvm_transaction; //传输数据包int id;int data;...
endclassclass producer extends uvm_component; //数据生产方producer...uvm_blocking_get_imp#(transaction,producer) get_imp; //定义端口function void build_phase(uvm_phase phase);get_imp = new("put_imp",this); //创建实例化端口endfunctionvirtual task get(output transaction tr); //在imp端口所在component中定义get()任务或者方法,output方向tr = transaction::type_id::create("tr",this); endtask
endclassclass consumer extends uvm_component; //数据接收方consumer...uvm_blocking_get_port#(transaction, consumer) get_port; //定义端口function void build_phase(uvm_phase phase);put_imp = new("put_imp",this); //创建实例化端口endfunctiontask run_phase(uvm_phase phase); get_port.get(tr); //通过imp所在component定义的get()处理数据,然后通过TLM传输数据endtask
endclassclass environment extends uvm_env; //环境层...producer p; //数据生产方consumer c; //数据接收方...virtual function void connect_phase(uvm_phase phase);c.get_port.connect(p.get_imp); //建立连接endfunction
endclass
2.2.transport( )操作传输
双向传输通信通过transport()任务实现。相当于一次put传输加一次get传输
,可以在同一任务调用过程中完成REQ和RSP的发出和返回;
在示意图上常常用方框表示Port,圆圈表示Export。
其他TLM操作还有peek,get_peek两种,但实际应用较少。
2.3.跨层次传输——uvm_analysis_port
在复杂的UVM TB中常用到port跨多级component连接的情形,在多层次连接中,connect要按控制流逐层进行连接。在一个path中,始终只会有一个imp作为连接的结尾。
class monitor extends uvm_monitor;...uvm_analysis_port#(transaction) analysis_port; //声明端口virtual function void build_phase(uvm_phase phase);this.analysis_port=new("analysis_port",this); //端口实例化endfunction
endclassclass agent extends uvm_agent;...monitor mon;uvm_analysis_port#(transaction) analysis_port; //声明端口virtual function void build_phase(uvm_phase phase);this.analysis_port=new("analysis_port",this); //端口实例化endfunctionvirtual function void connect_phase(uvm_phase phase);mon.analysis_port.connect(this.analysis_port); //相同端口的跨层次连接endfucntion
endclassclass environment extends uvm_env;...agent agt;scoreboard sb;...virtual function void connect_phase(uvm_phase phase);agt.analysis_port.connect(sb.analysis_imp); //不同端口类型连接endfucntion
endclass
三、一对多传输
前面通信有一个共同的地方即都是端对端的方式,同时在target一端需要实现传输方法,例如put()或者get()。这种方式在实际使用过程中也不免会给用户带来一些烦恼:
- 如何可以不自己实现这些传输方法,同时可以享受到TLM的好处
- 对于monitor、coverage collector等组件在传输数据时,会存在一端到多端的传输,如何解决这一问题。
3.1.fifo模式
uvm_tlm_fifo类是一个新的组件,它继承于uvm_component,且预先内置了多个端口、实现了多个对应方法供用户使用;功能类似mailbox #(T),该邮箱没有尺寸限制,用来存储数据类型T,而uvm_tlm_fifo的多个端口对应的方法都是利用该邮箱实现了数据读写。uvm_tlm_fifo所带的端口类型都是imp!!!
fifo之前采用put模式接口,后端采用get模式接口。
class my_env extends uvm_env;`uvm_component_utils (my_env)componentA compA;componentB compB;uvm_tlm_fifo #(transaction) tlm_fifo;//定义TLM FIFO... virtual function void build_phase (uvm_phase phase);super.build_phase (phase);compA = componentA::type_id::create ("compA", this);compB = componentB::type_id::create ("compB", this);tlm_fifo = new ("tlm_fifo", this, 2); //创建一个深度为2的FIFO,2省略,FIFO无限深endfunctionvirtual function void connect_phase (uvm_phase phase);compA.put_port.connect (tlm_fifo.put_export);compB.get_port.connect (tlm_fifo.get_export);endfunctionvirtual task run_phase (uvm_phase phase);forever begin#10 if (tlm_fifo.is_full ())//uvm_tlm_fifo常用的方法见UVM手册,FIFO为满时打印信息`uvm_info ("UVM_TLM_FIFO", "Fifo is now FULL !", UVM_MEDIUM)endendtask
endclass
monitor与modle之间的通信通过fifo模式,agent的端口为export为中间级。出現了跨层次传输,agent为中间层也需要设置端口。
3.2.分析端口——Analysis port(一对多传输、最常用)
UVM提供了一种分析端口(analysis port),它在组件中是以广播(broadcast)的形式向外发送数据的,而不管存在几个imp或者没有imp。分析端口的根据端口类型的不同分为:
- uvm_analysis_port、 uvm_analysis_export、 uvm_analysis_imp;
- 只有一个操作:write();
class componentB extends uvm_component;...uvm_analysis_port #(transaction) ap; //1.定义分析port端口...virtual function void build_phase (uvm_phase phase);super.build_phase (phase);ap = new ("analysis_port", this); //2.创建端口对象endfunctionvirtual task run_phase (uvm_phase phase);super.run_phase (phase); for (int i = 0; i < 5; i++) beginsimple_packet pkt = simple_packet::type_id::create ("pkt");pkt.randomize();ap.write (tr); //3.调用订阅端(subscriber)的write()方法,将数据发送出去endendtask
endclassclass subscriber extends uvm_component;... uvm_analysis_imp #(transaction, subscriber) analysis_export;//定义分析imp端口...virtual function void write (transaction tr); //4. 定义write()方法`uvm_info (get_full_name(), "Sub got transaction", UVM_MEDIUM)endfunction
endclass
class my_env extends uvm_env;`uvm_component_utils (my_env)componentA compA;componentB compB;sub sub1; sub sub2; sub sub3; function new (string name = "my_env", uvm_component parent = null);super.new (name, parent);endfunctionvirtual function void build_phase (uvm_phase phase);super.build_phase (phase);// Create an object of both componentscompA = componentA::type_id::create ("compA", this);compB = componentB::type_id::create ("compB", this);sub1 = sub::type_id::create ("sub1", this);sub2 = sub::type_id::create ("sub2", this);sub3 = sub::type_id::create ("sub3", this);endfunctionvirtual function void connect_phase (uvm_phase phase);compA.put_port.connect (compB.put_export); compB.ap.connect (sub1.analysis_export); //5.端口连接compB.ap.connect (sub2.analysis_export);compB.ap.connect (sub3.analysis_export);endfunction
endclass
在environment中通过分析端口将B与sub1、sub2、sub3连接:
1). 首先在componentB中定义分析port端口,并在run_phase阶段调用write()函数:
- uvm_analysis_port #(transaction) ap;
- ap.write (tr);
2)、 在分析端口的订阅端(subscriber) ,我们需要定义write()方法;
3)、在environment中通过分析端口将B与sub1、sub2、sub3连接 ,如下:
- compB.ap.connect (sub1.analysis_export);
- compB.ap.connect (sub2.analysis_export);
- compB.ap.connect (sub3.analysis_export);
参考:
Mr.翟的博客
UVM TLM
UVM-TLM通信机制(四)相关推荐
- UVM——TLM通信
UVM--TLM通信 1. 概述 2. 基本概念 3. 分类 4. 端口的使用 1. 概述 在芯片开发流程中,系统原型和芯片验证对项目的助推起到了关键作用 系统原型,一般是通过硬件功能描述文档来模拟硬 ...
- UVM基础-TLM通信机制(一)
目录 基本概念 TLM通信分类 单向通信 单向通信举例 单向通信代码 双向通信 多向通信 多向通信总结 通信管道 TLM FIFO Analysis Port Analysis TLM FIFO 芯片 ...
- UVM——TLM通信(1)
目录 TLM的定义 通信的端口定义和所在的组件 单向通信 定义 通信流程 多向通信 定义 通信流程 通信管道 定义 通信流程 前言:基于<UVM实战>和路科讲解的TLM通信,总结一下 TL ...
- UVM基础-TLM通信机制(二)
目录 TLM 2.0 通信 端口定义 传送数据 时间标记 同步通信元件 uvm_event uvm_event 总结 uvm_barrier uvm_callback TLM 2.0 通信 TLM 2 ...
- UVM TLM通信简介
1.UVM put/get通信 在UVM中一对一的TLM有很多种类型,以sequencer和driver为例. driver是请求端,在driver列化了两种端口(在uvm_driver中列化,可直接 ...
- UVM_6:事务级建模TLM通信
文章目录 前言 一.简单例子:driver-sequencer组件之间的通信 二.TLM通信 三.TLM通信步骤 四.TLM通信的分类 五.端口的使用 六.单向通信 七.双向通信 八.多向通信 1. ...
- TLM通信 — UVM
文章目录 简介 1.端口的使用 2.单向通信 3.双向通信 4.多向通信 5.通信管道 1. TLM_FIFO 2. Analysis Port 3. Analysis TLM FIFO 4. req ...
- python线程通信 消息传递_Python并发编程之线程消息通信机制/任务协调(四)
大家好,并发编程进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 .前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程无非 ...
- uvm基础(2)TLM通信,看这一篇就够了
tlm通信概述 tlm通信的步骤:1.分辨出initiator和target,producer和consumer. 2.在target中实现tlm通信方法. 3.在俩个对象中创建tlm端口. 4.在更 ...
最新文章
- nginx子请求并发处理
- eclipse开发javaweb项目配置tomcat
- matchers依赖_Hamcrest Matchers教程
- mysql聚集索引 myisam_一句话说清聚集索引和非聚集索引以及MySQL的InnoDB和MyISAM
- flutter 微信语言选择_Flutter/dart聊天实例|仿微信界面|红包|朋友圈
- BI/数据仓库/数据分析 基础入门:一些常见概念解释
- [msi]安装包无法安装,提示没有找到源文件xxx.cab
- Ant Desing Pro2.0(一)项目初始化
- c语言传址函数,关于c语言函数传址的规定
- EthChannel和STP01
- 2019.04.07 电商12 登录界面的验证
- axure树与表格结合_语言开发7:语言迟缓孩子,家庭日常训练,干货满满!【附:表格及图片】...
- python核心编程源代码
- 局域网内连接其他计算机共享的打印机
- matlab球面投影(二)
- win10鼠标停留任务栏不显示预览小窗口
- 信息系统安全 总结提纲
- 吴恩达深度学习笔记(40)-指数加权平均数优化算法
- 博途PLC的模糊PID(Matlab “fuzzy“工具箱使用介绍)
- 三、我的/登录 栏制作《仿淘票票系统前后端完全制作(除支付外)》
热门文章
- 计算机24游戏怎么玩,外媒评24款史上最好玩的策略游戏 投身宏伟场景玩到爆
- SpringBoot集成SpringSecurity(二) 个性化登录配置(remember-me mongodb)
- Java程序员掉发系列——程序员的成长之路
- 对耳朵伤害最小的耳机有哪些,不伤耳的蓝牙耳机推荐
- ROS小车基于yocs_smoother_velocity做速度平滑处理
- 联想G40笔记本U盘重装win7系统问题笔记
- “消费盲返”为什么可以在短短几天迅速爆火?
- Unity - 搬砖日志 - 获取 LODGroup 当前显示的 LOD 级别
- [工具]利用EasyRTSPClient工具检查摄像机RTSP流不能播放原因以及排查音视频数据无法播放问题...
- [08S01] 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is