1)基础用法:首先它是一个port,那么它肯定有对应export,我们在sequencer中定义一个analysis_port,在接收端定义一个tlm_fifo,然后在agent中将需要通信的两个component连接,在需要发送的时候,加入port.write(trans),然后通过get函数获取传递来的数据。
2)项目升级用法:唯一的区别是加入了p_sequencer的使用,调用对应的sequencr。
3)底层原理分析:
analysis_port(analysis_export)没有阻塞和非阻塞的概念。它是一个广播,不等与它相连的其他端口的响应。
analysis_port(analysis_export)必须连的imp是analysis_imp. analysis_imp所在的component必须定义个write的function --------- 注意:是function
从原理上看,analysis_port的作用是做广播(即port与imp相连,一对多),如下图所示:
在UVM里面做广播,首先我们需要造一个喇叭,也就是create一个analysis_port。然后要找来听众,也就是建立subscriber。
把听众的位置记录在一个小本本上,也就是在env里面执行analysis_base库的connect函数。
让听众接受到广播之后做出反应。这里面又分两步走,一是通过小本本来找听众的具体位置,这是要调用analysis_port中的write函数。二是找到听众后,让听众做该做的事,即在subscriber中具体实现write函数。
analysis_port是uvm_port_base的子类,分析uvm_port_base里面的connect函数。这里面用到了一个m_provided_by,它是uvm_port_base的声明变量数组,整个结合在一起看:jb_agent.jb_ap.connect(jb_sb.jb_analysis_export);
这句话做的事情就是,在agent的analysis_port里搞了一个数组,把jelly_bean_sb_subscriber 里面的jb_analysis_export存在这个数组里面。通俗地总结一下:connect这个函数所做的事情是把观众的位置记载一个表格上,但仅仅把位置记录在表格上不代表着内容广播出去了,实质上通过位置表格来找到观众并且把内容广播出去是在analysis_port的write函数里面实现的,下面分析一下write。
uvm_analysis_port里头只有一个write函数,也就是我们调用的那个,进入write源码看:这里面的get_if函数就是用来实现“顺着位置表格找观众的”,为了完成这个目的所使用的函数在uvm_port_base,在深入到这里面,用到一个m_imp_list,这就很熟悉了,和seq_item_port很类似了,它也在uvm_port_base里面,是一个系统自动调用的函数。
父类声明了一堆TLM的虚函数,也就是个空壳,那么这个write函数是在uvm_analysis_imp中实现,也就是subscriber,这里的analysis_export就跟我们connect函数连接的analysis_export对应上了。
此外还有analysis_port与analysis_imp的连接,就用put,try_put,can_put,get,try_get,can_get等函数,这里不过多介绍。