The put/get communication we have seen earlier typically require a corresponding export to supply the implementation. The idea behind having an analysis port is that a component like monitor should be able to generate a stream of transactions regardless of whether there is a target actually connected to it.
uvm_analysis_port is a specialized TLM based class whose interface consists of a single function
write () and can be embedded within any component as shown in the snippet below. This port contains a list of analysis exports that are connected to it. When the component (my_monitor) calls
analysis_port.write(), it basically cycles through the list and calls the
write() method of each connected export. If nothing is connected to it, then it simply does not do anything.
class my_monitor extends uvm_component; ... uvm_analysis_port #(my_data) analysis_port; ... endclass
The advantage lies in the fact that an analysis port may be connected to zero, one or many analysis exports and allows a component to call
write() method without depending on the number of connected exports. Also it's worth to note that
write() is a void function and hence will always complete within the same simulation delta cycle.