TLM port分类

  • port
  • export
  • imp

UVM TLM ports and exports are also used to send transaction objects cross different levels of testbench hierarchy.

Ports shall be used to initiate and forward packets to the top layer of the hierarchy. Exports shall be used to accept and forward packets from the top layer to destination. Implementation ports shall be used to define the put method at the target. Shown below are a few examples that use ports, exports and implementation for components at different hierarchy levels.

PORT互连规则

参考<uvm_port_base.svh>中的uvm_port_base中的connect函数,三种port的互联规则如下:

port连接到port

规则:只能是子port连接到父port。

Connecting port-to-port: CHILD.port.connect(PARENT.port)

port连接到export/imp

规则:port与export/imp有共同的祖父,即sibling可以是亲兄妹或者堂兄妹或者表兄妹

Connecting port-to-export: SIBLING.port.connect(SIBLING.export)
Connecting port-to-imp: SIBLING.port.connect(SIBLING.imp)

export连接到export/imp

规则:只能是父连子

Connecting export-to-export: PARENT.export.connect(CHILD.export)
Connecting export-to-imp: PARENT.export.connect(CHILD.imp)

连接方向

如上面所示,只能单向连接,不能反过来连接。

port类型

//-----------------
// Group: Port Type
//-----------------// Enum: uvm_port_type_e
//
// Specifies the type of port
//
// UVM_PORT           - The port requires the interface that is its type
//                      parameter.
// UVM_EXPORT         - The port provides the interface that is its type
//                      parameter via a connection to some other export or
//                      implementation.
// UVM_IMPLEMENTATION - The port provides the interface that is its type
//                      parameter, and it is bound to the component that
//                      implements the interface.typedef enum
{UVM_PORT ,UVM_EXPORT ,UVM_IMPLEMENTATION
} uvm_port_type_e;

常见的TLM port

uvm_analysis_port

该端口扩展子uvm_port_base,其中write函数的实现如下:

class uvm_analysis_port # (type T = int)extends uvm_port_base # (uvm_tlm_if_base #(T,T));function new (string name, uvm_component parent);super.new (name, parent, UVM_PORT, 0, UVM_UNBOUNDED_CONNECTIONS);m_if_mask = `UVM_TLM_ANALYSIS_MASK;  endfunctionvirtual function string get_type_name();return "uvm_analysis_port";endfunction// Method: write// Send specified value to all connected interface// Modified by Verdifunction void write (input T t);uvm_tlm_if_base # (T, T) tif;
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_BEGIN(t,"write");
`endiffor (int i = 0; i < this.size(); i++) begintif = this.get_if (i);if ( tif == null )uvm_report_fatal ("NTCONN", {"No uvm_tlm interface is connected to ", get_full_name(), " for executing write()"}, UVM_NONE);tif.write (t);end
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_END(t,"write");
`endifendfunction// End
endclass

这里的write()函数会通过遍历(this.get_if())查找出与该analysis port互联的所有的实现口。注意analysis port连接时可以是一对多的关系。比如连接关系可能包括:

  • port->port->export->export->imp
  • port->export->imp
  • port->imp

this.get_if()通过递归查找的方式找到所有imp,然后调用该实现口的write函数。我们再去看imp的write函数。

uvm_analysis_imp

// Modified by Verdi
class uvm_analysis_imp #(type T=int, type IMP=int)extends uvm_port_base #(uvm_tlm_if_base #(T,T));`UVM_IMP_COMMON(`UVM_TLM_ANALYSIS_MASK,"uvm_analysis_imp",IMP)function void write (input T t);
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_BEGIN(t,"write");
`endifm_imp.write (t);
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_END(t,"write");
`endifendfunction
endclass
// End

该参数化类的第二个参数是该imp例化时所在的uvm_componentcomponent type。比如该实现口例化在类aes_rm中,那么IMP=aes_rm。注意该write()函数的实现在IMP中,即示例aes_rm中。

uvm_analysis_export

//------------------------------------------------------------------------------
// Class: uvm_analysis_export
//
// Exports a lower-level <uvm_analysis_imp> to its parent.
//------------------------------------------------------------------------------class uvm_analysis_export #(type T=int)extends uvm_port_base #(uvm_tlm_if_base #(T,T));// Function: new// Instantiate the export.function new (string name, uvm_component parent = null);super.new (name, parent, UVM_EXPORT, 1, UVM_UNBOUNDED_CONNECTIONS);m_if_mask = `UVM_TLM_ANALYSIS_MASK;endfunctionvirtual function string get_type_name();return "uvm_analysis_export";endfunction// analysis port differs from other ports in that it broadcasts// to all connected interfaces. Ports only send to the interface// at the index specified in a call to set_if (0 by default).// Modified by Verdifunction void write (input T t);uvm_tlm_if_base #(T, T) tif;
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_BEGIN(t,"write");
`endiffor (int i = 0; i < this.size(); i++) begintif = this.get_if (i);if (tif == null)uvm_report_fatal ("NTCONN", {"No uvm_tlm interface is connected to ", get_full_name(), " for executing write()"}, UVM_NONE);tif.write (t);end
`ifndef UVM_VERDI_NO_PORT_RECORDING`UVM_IF_METHOD_END(t,"write");
`endifendfunction// End
endclass

write()函数很类似uvm_analysis_portwrite()函数,不同之处:

  • port type不一样,一个是UVM_PORT,一个是UVM_EXPORT

二者的m_if_mask都是UVM_TLM_ANALYSIS_MASK,连接的port数量均不受限制(UVM_UNBOUNDED_CONNECTIONS

uvm_tlm_fifo_base

该类为TLM FIFO类的基类,扩展自uvm_component,定义了两个端口put_export和get_peek_export用于存取transaction。

  // Port: put_export//// The ~put_export~ provides both the blocking and non-blocking put interface// methods to any attached port:////|  task put (input T t)//|  function bit can_put ()//|  function bit try_put (input T t)//// Any ~put~ port variant can connect and send transactions to the FIFO via this// export, provided the transaction types match. See <uvm_tlm_if_base #(T1,T2)>// for more information on each of the above interface methods.uvm_put_imp #(T, this_type) put_export;// Port: get_peek_export//// The ~get_peek_export~ provides all the blocking and non-blocking get and peek// interface methods:////|  task get (output T t)//|  function bit can_get ()//|  function bit try_get (output T t)//|  task peek (output T t)//|  function bit can_peek ()//|  function bit try_peek (output T t)//// Any ~get~ or ~peek~ port variant can connect to and retrieve transactions from// the FIFO via this export, provided the transaction types match. See// <uvm_tlm_if_base #(T1,T2)> for more information on each of the above interface// methods.uvm_get_peek_imp #(T, this_type) get_peek_export;  

该类的new()函数实例化了所有的端口:

  // Function: new//// The ~name~ and ~parent~ are the normal uvm_component constructor arguments. // The ~parent~ should be ~null~ if the uvm_tlm_fifo is going to be used in a// statically elaborated construct (e.g., a module). The ~size~ indicates the// maximum size of the FIFO. A value of zero indicates no upper bound.function new(string name, uvm_component parent = null);super.new(name, parent);put_export = new("put_export", this);blocking_put_export     = put_export;nonblocking_put_export  = put_export;get_peek_export = new("get_peek_export", this);blocking_get_peek_export    = get_peek_export;nonblocking_get_peek_export = get_peek_export;blocking_get_export         = get_peek_export;nonblocking_get_export      = get_peek_export;get_export                  = get_peek_export;blocking_peek_export        = get_peek_export;nonblocking_peek_export     = get_peek_export;peek_export                 = get_peek_export;put_ap = new("put_ap", this);get_ap = new("get_ap", this);endfunction

uvm_tlm_fifo

该类扩展自uvm_tlm_fifo_base,其详细功能描述如下:

//------------------------------------------------------------------------------
//
// Class: uvm_tlm_fifo#(T)
//
// This class provides storage of transactions between two independently running
// processes. Transactions are put into the FIFO via the ~put_export~.
// transactions are fetched from the FIFO in the order they arrived via the
// ~get_peek_export~. The ~put_export~ and ~get_peek_export~ are inherited from
// the <uvm_tlm_fifo_base #(T)> super class, and the interface methods provided by
// these exports are defined by the <uvm_tlm_if_base #(T1,T2)> class.
//
//------------------------------------------------------------------------------

以上描述中规定了该FIFO的输入输出端口的连接,即:

  • 通过put_export压入transaction
  • 通过get_peek_export获取transaction

该类中定义了一个mailbox,用于存储transaction。

local mailbox #( T ) m;

邮箱中存取transaction的实现如下:

  virtual task put( input T t );m.put( t );put_ap.write( t );endtaskvirtual task get( output T t );m_pending_blocked_gets++;m.get( t );m_pending_blocked_gets--;get_ap.write( t );endtask

调用的port是put_apget_ap

uvm_tlm_analysis_fifo

该类扩展自uvm_tlm_fifo,内部定义了一个新的export,如下:

class uvm_tlm_analysis_fifo #(type T = int) extends uvm_tlm_fifo #(T);// Port: analysis_export #(T)//// The analysis_export provides the write method to all connected analysis// ports and parent exports:////|  function void write (T t)//// Access via ports bound to this export is the normal mechanism for writing// to an analysis FIFO. // See write method of <uvm_tlm_if_base #(T1,T2)> for more information.uvm_analysis_imp #(T, uvm_tlm_analysis_fifo #(T)) analysis_export;// Function: new//// This is the standard uvm_component constructor. ~name~ is the local name// of this component. The ~parent~ should be left unspecified when this// component is instantiated in statically elaborated constructs and must be// specified when this component is a child of another UVM component.function new(string name ,  uvm_component parent = null);super.new(name, parent, 0); // analysis fifo must be unboundedanalysis_export = new("analysis_export", this);endfunctionconst static string type_name = "uvm_tlm_analysis_fifo #(T)";virtual function string get_type_name();return type_name;endfunctionfunction void write(input T t);void'(this.try_put(t)); // unbounded => must succeedendfunctionendclass

其中write()函数中的try_put()来自其父类uvm_tlm_fifo,其实现如下:

  virtual function bit try_put( input T t );if( !m.try_put( t ) ) beginreturn 0;endput_ap.write( t );return 1;endfunction  

try_put()除了将t压入邮箱m外,还将其推入put_ap(uvm_analysis_port类型),其作用是如果有外部其他的port和put_ap互联,则t同时传递到外部互联的端口去。try_get()函数也是类似的实现:

  virtual function bit try_get( output T t );if( !m.try_get( t ) ) beginreturn 0;endget_ap.write( t );return 1;endfunction

其中get_ap的定义在uvm_tlm_fifo_base中:

  uvm_analysis_port #(T) get_ap;

应用实例

sequencer和driver的互联

driver中通过port seq_item_port获取sequencer发出的transaction,其定义如下:

  // Port: seq_item_port//// Derived driver classes should use this port to request items from the// sequencer. They may also use it to send responses back.uvm_seq_item_pull_port #(REQ, RSP) seq_item_port;

与其互联的sequencer中的port为seq_item_export,其定义如下:

  // Variable: seq_item_export//// This export provides access to this sequencer's implementation of the// sequencer interface.//uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export;

在顶层agent中的互联如下:

drv.seq_item_port.connect(sqr.seq_item_export);

monior中的port

定义:

uvm_analysis_port #(my_transaction) analysis_port;  //TLM analysis port

使用:

analysis_port.write(tr);

rm中的port

port定义:

uvm_blocking_get_peek_port#(my_in_transaction) in_port;
uvm_blocking_put_port#(my_out_transaction) out_port;

port使用:

in_port.get(in_tr);
out_port.put(exp_tr);

env中的port

env中例化了三组FIFO(也可以不例化):

uvm_tlm_analysis_fifo#(my_in_transaction)        mon2rm_fifo;
uvm_tlm_analysis_fifo#(my_out_transaction)  rm2chk_fifo;
uvm_tlm_analysis_fifo#(my_out_transaction)      mon2chk_fifo;

互联关系如下:

iagt.mon.mon_analysis_port.connect(mon2rm_fifo.analysis_export);
rm.in_port.connect(mon2rm_fifo.blocking_get_peek_export);rm.out_port.connect(rm2chk_fifo.blocking_put_export);
chk.rm_in_port.connect(rm2chk_fifo.blocking_get_export);chk.mon_in_port.connect(mon2chk_fifo.blocking_get_export);
oagt.mon.mon_analysis_port.connect(mon2chk_fifo.analysis_export);

Note:根据uvm_tlm_fifo_base章节中new()函数的定义:

  • blocking_get_peek_export = get_peek_export
  • blocking_get_export = get_peek_export
  • blocking_put_export = analysis_export

checker中的port

port定义:

uvm_blocking_get_port#(my_out_transaction) rm_in_port;
uvm_blocking_get_port#(my_out_transaction) mon_in_port;

port使用:

rm_in_port.get(tr);
mon_in_port.get(tr);

使用_decl宏

引用一段uvm class reference中原话:

The TLM implemenation declaration macros provide a way for components to provide multiple implemenation ports of the same implementation interface. When an implementation port is defined using the built-in set of imps, there must be exactly one implementation of the interface.

The important thing to note is that each `uvm_imp_decl creates a new class of type uvm_imp, where suffix is the input argument to the macro. For this reason, you will typically want to put these macros in a seperate package to avoid collisions and to allow sharing of the definitions.

Summary

TLM Implementation Port Declaration Macros
The TLM implemenation declaration macros provide a way for components to provide multiple implemenation ports of the same implementation interface.
Macros
`uvm_blocking_put_imp_decl
`uvm_nonblocking_put_imp_decl
`uvm_put_imp_decl
`uvm_blocking_get_imp_decl
`uvm_nonblocking_get_imp_decl
`uvm_get_imp_decl
`uvm_blocking_peek_imp_decl
`uvm_nonblocking_peek_imp_decl
`uvm_peek_imp_decl
`uvm_blocking_get_peek_imp_decl
`uvm_nonblocking_get_peek_imp_decl
`uvm_get_peek_imp_decl
`uvm_blocking_master_imp_decl
`uvm_nonblocking_master_imp_decl
`uvm_master_imp_decl
`uvm_blocking_slave_imp_decl
`uvm_nonblocking_slave_imp_decl
`uvm_slave_imp_decl
`uvm_blocking_transport_imp_decl
`uvm_nonblocking_transport_imp_decl
`uvm_transport_imp_decl
`uvm_analysis_imp_decl

uvm_analysis_imp_decl为例,示例代码如下:

`uvm_analysis_imp_decl(_ingress)
`uvm_analysis_imp_decl(_egress)class myscoreboard extends uvm_component;uvm_analysis_imp_ingress#(mydata, myscoreboard) ingress;uvm_analysis_imp_egress#(mydata, myscoreboard) egress;mydata ingress_list[$];...function new(string name, uvm_component parent);super.new(name,parent);ingress = new("ingress", this);egress = new("egress", this);endfunctionfunction void write_ingress(mydata t);ingress_list.push_back(t);endfunctionfunction void write_egress(mydata t);find_match_in_ingress_list(t);endfunctionfunction void find_match_in_ingress_list(mydata t);//implement scoreboarding for this particular dut...endfunction
endclass

参考资料1: https://www.chipverify.com/uvm/tlm-preface
参考资料2:https://www.accellera.org/downloads/standards/uvm

UVM之TLM port基础相关推荐

  1. uvm 形式验证_UVM基础

    uvm_component与uvm_object 1. 几乎所有的类都派生于uvm_object,包括uvm_component. uvm_component有两大特性是uvm_object所没有的: ...

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

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

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

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

  4. UVM学习方法—基础入门篇(一)

    有不少工程师以为学习UVM就是简单的翻个书查个用户指南就可以学会,但其实这是非常困难的,很多人都看着指导资料无法下手,那么到底该怎么学习UVM呢? 什么是UVM 基于SV的验证方法学(可以简单理解为验 ...

  5. 【数字IC前端】UVM常见问题系列

    以下内容搬运自 数字芯片实验室 公众号,安利一波良心博主 (本人已为知识付费,只是搬运学习用作整理,希望大家也去付费支持一波) 原博文链接 1.什么是UVM?它的优势是什么? 2.uvm_compon ...

  6. uvm 形式验证_uvm面试题

    1.uvm_component与uvm_object之间的区别和联系? uvm_component类:是用于构成UVM仿真平台的组件,可组成树形结构,在bulid_phase中创建,之后整个仿真周期内 ...

  7. [UVM]UVM TLM1.0 Interface归纳总结 --- 图解UVM TLM1.0 Interface

    UVM TLM1.0 Interface归纳总结 --- 图解UVM TLM1.0 Interface Transaction-Level Modeling (TLM) 用户模块之间的通信. 是实现基 ...

  8. Easier UVM Coding Guidelines / 便捷UVM 编码指南

    简介,原则和目标 easier UVM是一组编码指南,附带一个代码生成器,可以创建符合本指南的UVM代码.创建easier UVM是为了帮助个人和项目团队学习,然后尽快使用UVM提高工作效率,并减轻在 ...

  9. 12、IC验证面试88问——phase机制、TLM、AP、sequencer、仲裁机制、vif、cb机制

    文章目录 Q51:main_phase要如何跳转到reset_phase? Q52:UVM 组件的通信方式 TLM 的接口分类和用法,peek 和 get的差异. Q53:Analysis port ...

最新文章

  1. 赠票 | 中国数据智能管理峰会(上海)
  2. nodejs windows 安装过程
  3. 我的第一篇Windows Live Writer小文
  4. 解决 Android ping IPv6 地址显示 network is unreachable 的问题
  5. Python 项目依赖包 第三方库 生成requirements.txt的两种方法
  6. 【DP】方格计数(nowcoder 20107-B)
  7. 机载计算机结构,机载计算机
  8. Python学习之==常用模块
  9. 正则提取Swagger在线文档里面的返回实体类字段
  10. HTTP请求头和响应头部包括的信息有哪些?(转)
  11. Rust常用编程概念之变量和可变性
  12. 获取 TUniConnection.SpecificOptions默认值和下拉框列表值
  13. 让SQL用户快速进入Hadoop大数据时代 —— Transwarp Inceptor是怎样炼成的
  14. mysql类似于excel的删除重复项_Excel去除重复项的三种常用技巧
  15. 【Cocos Creator 实战】01 - 如何做一款简单的拼图游戏
  16. Flutter路由管理和接收页面的返回值
  17. 离散型特征编码方式:one-hot与哑变量
  18. jQuary中delegate()函数的作用
  19. Html 语法学习笔记三
  20. 红黑树进阶—左倾红黑树(LLBR)介绍

热门文章

  1. 我想去 河南省 郑州春苑置业有限公司 上班 待遇好不好
  2. 在酒店怎么让你电脑的网速比别人快?
  3. Spring Cloud入门 -- Consul服务注册与发现(Hoxton.SR5版)
  4. 有哪些好用的视频录制软件?快进来学习一波
  5. EasyUI树形菜单后端
  6. STM32F7 使用 FAL 配置片上FLASH
  7. PHP 简单案例[1]
  8. csp试题2:公共钥匙盒
  9. python实现rar解压和压缩
  10. PDF转Word文字可编辑的软件有哪些?