概述
TLM通信的实现方式,这些通信有一个共同的地方即都是端对端的,同时在target一端需要实现传输方法,例如put()或者get()。
这种方式在实际使用也可能会给用户带来一些烦恼,如何可以不自己实现这些传输方法,同时可以享受到TLM的好处?
对于monitor、coverage collector等组件在传输数据时,会存在一端到多端的传输,如何解决这一问题?
几个TLM组件和端口可以帮助用户免除这些烦恼:
- TLM FIFO
- analysis port
- analysis TLM FIFO
- request&response 通信管道
TLM_FIFO
FIFO的本质时一块缓存加两个IMP。
在一般TLM传输过程中,无论是initiator给target发起一个transaction,还是initiator从target获取一个transaction,transaction最终都会流向consumer中(initiator和target都可以是consumer)。consumer在没有分析transaction时,我们希望将该对象先存储到本地FIFO中供稍后使用。
用户需要分别在两个组件中例化端口,同时在target中实现相应的传输方法。
多数情况下,需要实现的传输方法都是相似的,方法的主要内容即是为了实现一个数据缓存功能。
TLM FIFO uvm_tlm_fifo类是一个新组件,它继承于uvm_component类,而且已经预先内置了多个端口以及实现了多个对应方法供用户使用。
uvm_tlm_fifo的功能类似于mailbox,不同的地方在于uvm_tlm_fifo提供了各种端口供用户使用。推荐在initiator端例化put_port或者get_peek_port,来匹配uvm_tlm_fifo的端口类型。
当然,如果用户例化了其它类型的端口,uvm_tlm_fifo还提供put、get以及peek对应的端口:
uvm put_imp #(T,this_type)blocking put_export;
uvm put_imp #(T,this_type)nonblocking put_export;
uvm_get_peek_imp #(T,this_type)blocking_get_export;
uvm_get_peek_imp #(T,this_type)nonblocking_get_export;
uvm get_peek_imp #(T,this_type)get_export;
uvm get_peek_imp #(T,this_type)blocking peek_export;
uvm get_peek_imp #(T,this_type)nonblocking peek_export;
uvm get_peek_imp #(T,this_type)peek_export;
uvm_get_peek_imp #(T,this_type)blocking_get peek_export;
uvm get_peek_imp #(T,this_type)nonblocking get peek export;
Analysis Port
- 除了端对端的传输,在一些情况下还有多个组件会对同一个数据进行运算处理。
- 如果这个数据是从同一个源的TLM端口发出到达不同组件,这就要求该种端口可以满足从一端到多端的需求。
initiator.ap.connect(targetl.aimp);
initiator.ap.connect(target2.aimp);
initiator.ap.connect(target3.aimp);
如果数据源端发生变化需要通知跟它关联的多个组件时,我们可以利用软件的设计模式之一观察者模式(observer pattern)来实现。
observer pattern的核心在于:
1、第一,这是从一个initiator端到多个target端的方式。
2、第二,analysis port采取的是“push"模式,即从initiator端调用多个target端的write()函数来实现数据传输。
一个典型的analysis port类型端囗的连接方式,类似于其它TLM端口的是,按照传输方法和端口方向组合可以将analysis port分为uvm_analysis_port、uvm_analysis_export以及uvm_analysis_imp。
其中PORT、EXPORT和IMP同uvm_analysis_port、uvm_analysis_export以及uvm_analysis_imp的区别如下:
第一,默认情况下,一个analysis port(analysis_export)可以连接多个IMP,也就是说,analysis_port(analysis_export)与IMP之间的通信是一对多的通信,而put和get系列端口与相应IMP的通信是一对一的通信(除非在实例化时指定可以连接的数量)。analysis_port(analysis_export)更像是一个广播。
第二,put与get系列端口都有阻塞和非阻塞的区分。但是对于analysis_port和analysis_export来说,没有阻塞和非阻塞的概念。因为它本身就是广播,不必等待与其相连的其他端口的响应,所以不存在阻塞和非阻塞。
target一侧例化了uvm_analysis_imp后还需要实现write()函数。
在顶层可以将initiator端的uvm_analysis_port同多个target端的uvm_analysis_imp进行连接。
在initiator端调用write()函数时,实际上它是通过循环的方式将所有连接的target端内置的write()函数进行了调用。
由于函数立即返回的特点,无论连接多少个target端,initiator端调用write()函数总是可以立即返回的。不同于之前单一端口函数调用的是,即使没有target与之相连,调用write()函数时也不会发生错误
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()函数:
uvm_analysis_imp #(T,uvm_tlm_analysis_fifo #(T))analysis_export;
基于initiator到多个target的连接方式,用户如果想实现一端到多端的数据传输,可以插入多个uvm_tlm_analysis_fifo,给出连接方式如下:
- 将initiator的analysis_port连接到tlm_analysis_fifo的get_export端口,这样数据可以从initiator发起,写入到各个tlm_analysis_fifo的缓存中。
- 将多个target的get_port连接到tlm_analysis_fifo的get_export,注意保持端口类型的匹配,这样从target一侧只需要调用get()方法就可以得到先前存储在tlm_analysis_fifo中的数据。
initiator.ap.connect(tlm_analysis_fifol.analysis_export);
target1.get_port.connect(tlm_analysis_fifo1.get_export);
initiator.ap.connect(tlm_analysis_fifo2.analysis_export);
targert2.get_port.connect(tlm_analysis_fifo2.get_export);
initiator.ap.connect(tlm_analysis_fifo3.analysis_export);
targets.get_port.connect(tlm_analysis_fifo3. get_export);
FIFO中有两个IMP,但是在上面的连接关系中,FIFO中却是EXPORT,这是因为FIFO中的analysis_export和blocking_get_export虽然名字中有关键字export,但是其类型却是IMP。UVM为了掩饰IMP的存在,在它们的命名中加入了export关键字。
Request & Response通信管道
双向通信端口transport,即通过在target端实现transport()方法可以在一次传输中既发送request又可以接收response。
UVM提供了两种简便的通信管道,它们作为数据缓存区域,既有TLM端口从外侧接收request和response,同时也有TLM端口供外侧获取request和response。这两种TLM通信管道分别是:
- uvm_tlm_req_rsp_channel
- uvm_tlm_transport_channel
有了这么多丰富的端口,用户可以在使用成对的端口进行数据的存储和访问。需要注意的是,uvm_tlm_req_rsp_channel内部例化了两个mailbox分别用来存储request和response: - protected uvm_tlm_fifo#(REQ)m_request_fifo;
- protected uvm_tlm_fifo#(RSP)m_response_fifo;
这篇笔记参考《UVM实战》、《芯片验证漫游指南》和某验证视频整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。