通信管道

一、概述

TLM通信的实现方式有一个共同的地方即都是端对端的,同时target一端需要实现传输方法,例如put()或者get()。如何不自己实现这些方法?对于monitorcoverage collector等组件在传输数据时,会存在一端到多端的传输?怎么解决!

二、TLM_FIFO

  •  在一般TLM传输过程中,无论是initiator给target发起一个transaction,还是initiator从target获取一个transaction,transaction最终都会流向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端到多个target端的方式。
  • analysis port采取的是“push”模式,即从initiator端调用多个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的analysis_export端口,这样数据可以从initiator发起,写入到各个tlm_analysis_fifo的缓存中。
  • 将多个target的get_port连接到tlm_analysis_fifo的get_export端口,注意保持端口类型的匹配,这样从target一侧只需要调用get()方法就可以得到先前存储在tlm_analysis_fifo中的数据。
initiator.ap.connect(tlm_analysis_fifo1.analysis_export);
target1.get_port.connect(tlm_analysis_fifo1.get_export);

initiator.ap.connect(tlm_analysis_fifo2.analysis_export);
target2.get_port.connect(tlm_analysis_fifo2.get_export);

initiator.ap.connect(tlm_analysis_fifo3.analysis_export);
target3.get_port.connect(tlm_analysis_fifo3.get_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
它提供的端口首先是单一方向的

uvm_put_export #(REQ) put_request_export;
uvm_put_export #(RSP) put_response_export;
uvm_get_peek_export #(RSP) get_peek_response_export;
uvm_get_peek_export #(REQ) get_peek_request_export;
uvm_analysis_port #(REQ) request_ap;
uvm_analysis_port #(RSP) response_ap;
uvm_master_imp #(REQ, RSP, this_type, uvm_tlm_fifo #(REQ), uvm_tlm_fifo #(RSP)) master_export;
uvm_slave_imp #(REQ, RSP, this_type, uvm_tlm_fifo #(REQ), uvm_tlm_fifo #(RSP)) slave_export;

 可以在使用成对的端口进行数据的存储和访问。需要注意的是,uvm_tlm_req_rsp_channel内部例化了两个mailbox分别用来存储request和response

protect uvm_tlm_fifo #(REQ) m_request_fifo;
protect uvm_tlm_fifo #(RSP) m_response_fifo;

例如initiator端可以连接channel的put_request_export,target连接channel的get_peek_request_export,同时target连接channel的put_response_export,initiator连接channel的get_peek_response_export端口。

通过这种对应的方式,使得initiator与target可以利用uvm_tlm_req_rsp_channel进行request与response的数据交换

initiator.put_port.connect(req_rsp_channel.put_request_export);
target.get_peek_port.connect(req_rsp_channel.get_peek_request_export);
target.put_port.connect(req_rsp_channel.put_response_export);
initiator.get_peek_port.connect(req_rsp_channel.get_peek_response_export);

 也可以利用另一种连接方式

initiator.master_port.connect(req_rsp_channel.master_export);
target.slave_port.connect(req_rsp_channel.slave_export);

uvm_tlm_transport_channel
在uvm_tlm_req_rsp_channel的基础上,UVM又添加了具备transport端口的管道组件uvm_tlm_transport_channel类,它继承于uvm_tlm_req_rsp_channel,并且例化了transport端口uvm_transport_imp #(REQ, RSP, this_type) transport_export

新添加的这个TLM FIFO组件类型是针对于一些无法流水化处理的request和response传输,例如initiator一端要求每次发送完request,必须等到response接收到以后才可以发送下一个request,这时transport()方法就可以满足这一需求。

将initiator端到req_rsp_channel的连接修改为 

initiator.transport_port.connect(transport_channel.transport_export)

transport_channel和target之间的连接,可以保留之前的单向传输连接方式。

猜你喜欢

转载自blog.csdn.net/Arvin_ing/article/details/127710402
今日推荐