UVM TLM的实现方式

在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等

UVM TLM的实现方式

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等。