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的流向,我们又可以将两个对象分为producerconsumer。区分它们的方法:

  • producer:生产数据方,即为producer;
  • consumer:接收数据方,即为consumer;

1.2.三个通信端口:port、export、imp

通信端口按照类型可以划分为三种:

  1. port:通信请求方initiator的发起端,initiator凭借port端口才可以访问target。
  2. export:作为initiator和target中间层次的端口
  3. 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通信机制(四)相关推荐

  1. UVM——TLM通信

    UVM--TLM通信 1. 概述 2. 基本概念 3. 分类 4. 端口的使用 1. 概述 在芯片开发流程中,系统原型和芯片验证对项目的助推起到了关键作用 系统原型,一般是通过硬件功能描述文档来模拟硬 ...

  2. UVM基础-TLM通信机制(一)

    目录 基本概念 TLM通信分类 单向通信 单向通信举例 单向通信代码 双向通信 多向通信 多向通信总结 通信管道 TLM FIFO Analysis Port Analysis TLM FIFO 芯片 ...

  3. UVM——TLM通信(1)

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

  4. UVM基础-TLM通信机制(二)

    目录 TLM 2.0 通信 端口定义 传送数据 时间标记 同步通信元件 uvm_event uvm_event 总结 uvm_barrier uvm_callback TLM 2.0 通信 TLM 2 ...

  5. UVM TLM通信简介

    1.UVM put/get通信 在UVM中一对一的TLM有很多种类型,以sequencer和driver为例. driver是请求端,在driver列化了两种端口(在uvm_driver中列化,可直接 ...

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

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

  7. TLM通信 — UVM

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

  8. python线程通信 消息传递_Python并发编程之线程消息通信机制/任务协调(四)

    大家好,并发编程进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 .前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程无非 ...

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

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

最新文章

  1. nginx子请求并发处理
  2. eclipse开发javaweb项目配置tomcat
  3. matchers依赖_Hamcrest Matchers教程
  4. mysql聚集索引 myisam_一句话说清聚集索引和非聚集索引以及MySQL的InnoDB和MyISAM
  5. flutter 微信语言选择_Flutter/dart聊天实例|仿微信界面|红包|朋友圈
  6. BI/数据仓库/数据分析 基础入门:一些常见概念解释
  7. [msi]安装包无法安装,提示没有找到源文件xxx.cab
  8. Ant Desing Pro2.0(一)项目初始化
  9. c语言传址函数,关于c语言函数传址的规定
  10. EthChannel和STP01
  11. 2019.04.07 电商12 登录界面的验证
  12. axure树与表格结合_语言开发7:语言迟缓孩子,家庭日常训练,干货满满!【附:表格及图片】...
  13. python核心编程源代码
  14. 局域网内连接其他计算机共享的打印机
  15. matlab球面投影(二)
  16. win10鼠标停留任务栏不显示预览小窗口
  17. 信息系统安全 总结提纲
  18. 吴恩达深度学习笔记(40)-指数加权平均数优化算法
  19. 博途PLC的模糊PID(Matlab “fuzzy“工具箱使用介绍)
  20. 三、我的/登录 栏制作《仿淘票票系统前后端完全制作(除支付外)》

热门文章

  1. 计算机24游戏怎么玩,外媒评24款史上最好玩的策略游戏 投身宏伟场景玩到爆
  2. SpringBoot集成SpringSecurity(二) 个性化登录配置(remember-me mongodb)
  3. Java程序员掉发系列——程序员的成长之路
  4. 对耳朵伤害最小的耳机有哪些,不伤耳的蓝牙耳机推荐
  5. ROS小车基于yocs_smoother_velocity做速度平滑处理
  6. 联想G40笔记本U盘重装win7系统问题笔记
  7. “消费盲返”为什么可以在短短几天迅速爆火?
  8. Unity - 搬砖日志 - 获取 LODGroup 当前显示的 LOD 级别
  9. [工具]利用EasyRTSPClient工具检查摄像机RTSP流不能播放原因以及排查音视频数据无法播放问题...
  10. [08S01] 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is