TLM通信

TLM 的定义


TLM 是 Transaction Level Modeling (事务级建)的缩写它起源于 Systen通信标准所谓 transacion level 是相对 DUT 中各个模块之间信号线级别的通信来简单来说,一个transacion就是把具有某一特定功的一组信息封装在一起而成为的类。如 my_transaction 就是把一个MAC 里的各个字段封装在了一起。

TLM 通信中的3种操作:

1) put 操作,如图 1 所示,通信的发起者 A把一个 transaction 发送给 B。在这程中,A 称为“发起者”,而B 称为“目标”。A具有的端口(用方框表示)称为 PORTB 的端口(用圆圈表示)称为 EXPORT。这个过程中,数据流是从 A 流向 B 的

2) get操作,如图2所示, A向 B 索取一个transaction。在这个过程中, A  依然是发起者”,B 依然是“目标”,A上的端口依然是 PORT,而B 上的端口依然是 EXPORT。这过程中,数据流是从 B 流向 A 的。到这里,读者应该意识到,PORT 和 EXPORT 体现的控制流而不是数据流。因为在 put 操作中,数据流是从 PORT 流向 EXPORT 的,而在 a作中,数据是从 EXPORT 流向 PORT 的。但是无论是 get 还是 put 操作,其发起者拥有的是PORT端口,而不是 EXPORT。作为一个EXPORT 来说,只能被动地接收PORT 的命令。

3) transport操作,如图3所示,transport操作相当于一次 put 操作加一次 get 操作,这两次操作的“发起者”都是A,目标都是 B。A上的端口依然是PORT,而B上的端口依然是EXPORT。在这个过程中,数据流先从A流向 B,再从B流向A。在现实世界中,相当于是A向B 提交了一个请求 (request),而B 返回给A一个应答(response)。所以这种 transport 操作也常常被做request-response 操作put、get和 transport 操作都有阻塞和非阻塞之分。


4.1.3UVM中的 PORT与EXPORT


UVM提供对TLM操作的支持,在其中实现了PORT与EXPORT。对应于不同的操作,有不同的PORT,UVM 中常用的PORT有:

uvm_blocking_put_port# (T);
uvm_nonblocking_put_port# (T);
uvm_put_port#(T);

uvm_blocking_get_port# (T);
uvm_nonblocking_get_port# (T);
uvm_get_port# (T);

uvm_blocking_peek_port# (T);
uvm_nonblocking_peek_port# (T);
uvm_peek_port# (T);

uvm_blocking_get_peek_port# (T);
uvm_nonblocking_get_peek_port#(T);
uvm_get_peek_port# (T);

uvm_blocking_transport_port# (REO,RSP);
uvm_nonblocking_transport_port# (REQ,RSP);
uvm_transport_port# (REQ,RSP);

这 15 个端口中前 12个定义中的参数就是这个PORT 中的数据类型,而最后 3 个定义中的参数则表示 transport 操作中发起请求时传输的数据类型和返回的数据类型。

export端口同上

PORT和EXPORT体现的是一种控制流,在这种控制流中,PORT具有高优先级EXPORT具有低优先级。只有高优先级的端口才能向低优先级的端口发起三种操作。

UVM中各种端口的互连

    PORT与EXPORT的连接

UVM中使用connect函数来建立连接关系。如A要和B通信(A是发起者),那么可以这么写:A.port.connect(B.export).

//组件A
class A extends uvm_component;
  
    'uvm_componentutils(A)
    
     uvm_blocking_put_port# (my_transaction) A_port;
endclass

function void A::build_phase (uvm_phase phase);
      
         super.build_phase(phase);
         A_port=new("A_port",this);
endfunction
//组件B
class B extends uvm_component;
  
    'uvm_componentutils(A)
    
     uvm_blocking_put_export# (my_transaction) B_export;
endclass

function void A::build phase (uvm_phase phase);
      
         super.build_phase(phase);
         B_export=new("B_export",this);
endfunction

//env连接两个组件

class my env extends uvm_env;
A A_inst;
B B_inst;

virtual function void build_phase (uvm_phase phase) ;
   A_inst = A::type_id::create("A_inst", this);
   B_inst = B::type_id::create("B_inst", this);
endfunction
endclass

function void my_env::connect_phase (uvm_phase phase);
    super.connect_phase(phase);
    A_inst.A_port.connect(B_inst.B_export);
endfunction

UVM中的IMP


除了TLM 中定义的PORT与EXPORT外,UVM中加人了第三种端口:IMP

UVM 中的IMP 如下所

uvm_blocking_put_imp#(T,IMP);
uvm_nonblocking_put imp#(T,IMP);
uvm_put_imp#(T,IMP);

uvm_blocking_get_imp#(T,IMP);
uvm_nonblocking_get_imp#(T,IMP);
uvm_get_imp#(T,IMP);

uvm_blocking_peek_imp#(T,IMP);
uvm_nonblocking_peek imp#(T,IMP);
uvm_peek_imp# (T,IMP);

uvm_blocking_get_peek_imp#(T,IMP);
uvm_nonblocking_get_peek_impt#(T, IMP);
uvm_get_peek_imp# (T,IMP);
uvm_blocking_transport_imp#(REO,RSP,IMP);
uvm_nonblocking_transport_imp#(REQ,RSP,IMP);
uvm_transport_imp#(REQ, RSP,IMP);

通信时作为被动承担者。

按照控制流的优先级排序,UVM 中三种端口顺序为: PORT、EXPORT、IMP。

IMP 的优先级最低,一个PORT 可以连接到一个IMP并发起三种操作,反之则不行。

前六个IMP 定义中的第一个参数T是这个IMP 传输的数据类型。第二个参数IMP,UVM 文档中把其解释为实现这个接口的一个 component。

PORT与IMP连接

uvm_blocking_put_port# (my_transaction) A_port;
uvm_blocking_put_imp# (my_transaction, B) B_imp;
 A_inst.A_port.connect(B_inst.B_imp);

 EXPORT与IMP连接

uvm_blocking_put_export# (my_transaction) A_export;
uvm_blocking_put_imp# (my_transaction, B) B_imp;
 A_inst.A_export.connect(B_inst.B_imp);

PORT与PORT连接 

在 UVM中、支持带层次的连接关系,如图所示。

 A与C中是PORT,B中是IMP。UVM支持C的PORT连接到A的POR并最终连接到B的IMP。

uvm_blocking_put_port#(my_transaction) C_port;
uvm_blocking_put_port#(my_transaction) A_port;
uvm_blocking_put_imp#(my_transaction) B_imp;
 A_inst.A_port.connect(C_inst.C_port);

EXPORT与EXPORT连接  

C_inst.C_export.connect(B_inst.B_export);
​
A_inst.A_port.connect(C_inst.C_export);

​

  blocking_get端口

要实现A到B的通信,使用blocking_get端口
在这种连接关系中,数据流依然是从A 到 B,但是 A 由动作发起者变成了动作接收者,而 B 由动作接收者变成了动作发起者.

B_port 的类型为uvm_blocking_get_ port,

A_export 的类型为uvm_blocking_get_ export

A_imp 的类型为uvm_blocking_get_imp。

与uvm blocking_put_ imp 所在的 component要现一个put 的函数/任务类似,uvm_ blocking_get _imp 所在的component要实现一个名字get 的函数/任务。

 blocking_transport 端口


transport系列端口与put和get 系列端口都不一样。在 put 和get 系列端口中,所有的通信都是单向的,而在 transport系列端口中,通信变成了双向的。

Analysis 端口


analysis port (analysis export)与IMP之间的通信是一对多的通信,没有阻塞和非阻塞的概念。

一个analysis port 可以和多个MP 相连接进行通信,但是IMP 的类型必须是uvmanalysis imp,否则会报错。

 在analysis imp 所在的 component,必须定义一个名字为 write 的函数。

TLM_FIFO

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 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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值