UVM 史上最全TLM单向/双向/多向通信介绍
文章目录
一、TLM单向通信
1.概述
单向通信(unidirectional communiction)指的是从initiator到target之间的数据流向是单一方向的,或者说initiator和target只能扮演producer和consumer中的一个角色。在UVM中,单一数据流向的TLM端口有很多类型:
uvm_blocking_put_PORT
uvm_nonblocking_put_PORT
uvm_put_PORT
uvm_blocking_get_PORT
uvm_nonblocking_get_PORT
uvm_get_PORT
uvm_blocking_peek_PORT
uvm_nonblocking_peek_PORT
uvm_peek_PORT
uvm_blocking_get_peek_PORT
uvm_nonblocking_get_peek_PORT
uvm_get_peek_PORT
2.类型
这里的PORT代表了三种端口名:port、export和imp。按照UVM端口名的命名规则,指出了通信的两个要素:
- 是不是阻塞的方式(即可以等待延时)
- 何种通信方法
3.方法
- 阻塞传输方式将blocking前缀作为函数名的一部分,而非阻塞方式则名为nonblocking。阻塞端口的方法类型为task,这保证了可以实现事件等待和延时;非阻塞端口的方式类型为function,这确保了方法调用可以立即返回。
- 我们才方法名也可以发现,例如uvm_blocking_put_PORT提供的方法task put()会在数据传送完后返回,uvm_non_blocking_put_PORT对应的两个函数try_put()和can_put()是立刻返回的。
- uvm_put_PORT则分别提供了blocking和nonblocking的方法,这为通讯方式提供了更多选择。blocking阻塞传输的方法包含:
1.put():initiator先生成数据Tt,同时将该数据传送至target。
2.get():initiator从target获取数据Tt,而target中的该数据Tt则应消耗。
3.peek():initiator从target获取数据Tt,而target中的数据Tt还应保留。 - 与上述三种任务对应的nonblocking非阻塞方法分别是:
1.try_put()
2.can_put()
3.try_get()
4.can_get()
5.try_peek()
6.can_peek() - 这六个非阻塞函数与对应阻塞任务的区别在于,它们必须立即返回,如果try_xxx函数可以发送或者获取数据,那么函数应该返回1,如果执行失败则应该返回0。
- 可以通过can_xxx函数先试探target是否可以接收数据,如果可以,再通过try_xxx函数发送,提高数据发送的成功率。
4.单向通信例子
class itrans extends uvm_transaction;
int id;
int data;
...
endclass
class otrans extends uvm_transaction;
int id;
int data;
...
endclass
class compl extends uvm_component;
uvm_blocking_put_port #(itrans) bp_port;
uvm_nonblocking_get_port #(otrans) nbg_port;
`uvm_component_utils(comp1)
...
task run_phase(uvm_phase phase);
itrans itr;
otrans otr;
int trans_num=2;
fork
begin
for(int i=0;i<trans_num;i++)begin
itr=new("itr",this);
itr.id=i;
itr.data='h10+i;
this.bp_port.put(itr);
`uvm_info("PUT",$sformatf("put itrans id:'h%0x, data:'h%0x",itr