1、analysis端口主要用于一对多通信,即一个analysis_port(analysis_export)可以连接多个IMP。analysis_port(analysis_export)与IMP之间的通信是一对多的通信,而put和get系列端口与相应IMP的通信是一对一的通信。(除非在实例化时指定可以连接的数量)。analysis_port(analysis_export)更像是一个广播。
2、put与get系列端口都有阻塞和非阻塞的区分。但是对于analysis_port和analysis_export来说,没有阻塞和非阻塞的概念。 因为它本身就是广播,不必等待与其相连的其他端口的响应,所以不存在阻塞和非阻塞。
3、一个analysis_port可以和多个IMP相连接进行通信,但是IMP的类型必须是uvm_analysis_imp,否则会报错。
4、对于put系列端口,有put、try_put、can_put等操作,对于get系列端口,有get、try_get和can_get等操作。对于analysis_port和 analysis_export来说,只有一种操作:write。在analysis_imp所在的component,必须定义一个名字为write的函数。
5、与put系列端口的PORT和EXPORT直接相连会出错的情况一样,analysis_port如果和一个analysis_export直接相连也会出错。只有在analysis_export后面再连接一级uvm_analysis_imp,才不会出错。
例子:uvm_subscriber,派生自uvm_component,但是没有过多扩展,仅仅加了一个analysis_imp(analysis_export),同时定义了一个纯虚函数write。主要用于覆盖率收集:
1、用户可以定义自己的覆盖率cov派生自uvm_subscriber,再定义 write 方法(uvm_subscriber 类中声明是纯虚方法,因此必须重新定义)。
2、这样的好处是在自己的覆盖率cov里面不用再定义一个analysis_imp端口,可以直接在env的connect_phase里面直接将定义的analysis_port(这个需要自己在相应的class里面定义)与cov的analysis_imp进行连接。
3、一般是将monitor的analysis port连接到subscriber(或者他的派生类),将transaction传递过来,做function coverage。
virtual class uvm_subscriber #(type T=int) extends uvm_component;
typedef uvm_subscriber #(T) this_type;
uvm_analysis_imp #(T, this_type) analysis_export;
function new (string name, uvm_component parent);
super.new (name, parent);
analysis_export = new ("analysis_imp", this);
endfunction
pure virtual function void write (T, t);
endclass