在UVM 框架中中,组件之间transaction的传输通过TLM机制实现的,这样对组件的复用性以及各个组件之间的独立性带来了极大的好处,想一想如果么有TLM机制,怎么实现transaction的传输呢,可以会使用SV中的mailbox,在两个将要通信的组件之间各个声明一个mailbox句柄,然后在父一层将两个句柄连接在一块,这样如果不仅仅增加了代码量,同时如果在复用的时候,组件通信的关系发生改变,这样子还需要在顶层修改代码,没有做到组件之间的独立性。而是用TLM,只需要在顶层修改连接关系即可。TLM机制说白了就是将之前使用SV的方法封装到一个特定的class中(这也体现了为什么UVM是方法学,他是在SV带的基础上进一步封装)
- 在TLM中常用的主要分为3类端口
(1)put/imp/export/analysis等
(2)fifo端口
(3)sequencer--------driver之间的端口
fifo端口:其中fifo继承与uvm_component,本身就是一个组件类,在组件中实现了需要的方法,比如put方法,get方法等,同时这个类中声明了很多个我们使用的put/imp/export/analysis port等

put/imp/export/:
上图以uvm_blocking_put_port和uvm_blocking_put_imp为例子来讲解一下
首先有两条路径(1)uvm-tlm-ifs->uvm_port_base->uvm_blocking_put_port/uvm_blocking_put_imp
(2)uvm-component->uvm-port_component_base->uvm_port_component
在uvm_blocking_put_port中重载了put方法,这个put方法调用的是连接到这个port上的uvm_blocking_put_imp的put方法,在uvm_blocking_put_imp也重载了put方法,而uvm_blocking_put_imp中的put方法调用的是imp所在uvm_component父组件的put方法,为什么可以这么使用呢,核心在于在uvm-port-base中有uvm-port-component这个类实例,同时在uvm-port-component中有uvm-port-base这个类实例,相互之间实现了相互调用。
强调一点port端口必须最终要连接到imp上,或者通过export连接到imp上。如果没有的话当port调用put方法时,调用的是imp.put(),这个时候会出现imp为null的情况,会出错。
具体实现port和imp的相互连接方法是在reslove_binding函数中执行的。普通的组件这个函数是空函数,uvm-port-component组件会调用内置的uvm-port-base的同名函数,从而实现port和imp的互联。
sequencer--------driver之间的端口:
sequencer和driver之间的端口类型和上面基本一样,只是需要在sequencer中多实现一些方法,比如get-next-item等。
- 双向端口
主要是mast_port/mast_imp大类,slave_port/slave_imp大类,transport大类
master,slave相对于以上的单向端口比如put/get/get_peek等,本质上仅仅是多重载了一些方法,使得通过一个端口既可以调用put,又可以调用get
Mast_port/mast_imp:内建put,get,peek等方法,在Mast_port端口处调用put(req),同时也可以调用get(rsp)。即一直是initiator,但是可以同时作为transtration的producer和consumer。(通过一个端口接可以解决),相当于put端口,req有initiator产生,rsp由target产生
Slave_port/slave_imp: 内建put,get,peek等方法,在Mast_port端口处调用get(req),同时也可以调用put(rsp)。即一直是initiator,但是可以同时作为transtration的producer和consumer。(通过一个端口接可以解决),相当于get端口,req由target产生,rsp由initiator产生
Transport:
Transport_port/transport_imp
这个端口类型和上面的都不太类似,这个端口最终会调用imp组件一侧的transport方法,trasnport方法调用结束以后consumer一侧拿到了req,同时producer一侧拿到了rsp,这个与上面的mast_port/slave_port不一样
Task transport(itrans req,output otrans rsp)。
关于双向端口,具体的实现方式有上面提到的图相似,这里就不说明了。
双向端口的与单向端口的本质区别在于,req和rsp的transtration类型可以是不一样的。