Difference Between the uvm_analysis ports

Can you please help to understand the functionality and clear difference between:

  1. uvm_analysis_export
  2. uvm_analysis_port
  3. uvm_analysis_imp

I have searched in internet, there are some explanations, like those:

But still I feel that need more explanation. Can someone help please.

2 Answers

uvm_analysis_port's are the publisher, they broadcast transactions

uvm_analysis_imp's are the subscriber, they receive transactions and call a function named 'write' in the class in which they are defined.

uvm_analysis_export's can be more confusing, they are used to expose 'imp' ports at higher level of the hierarchy. For example if you have an agent which contains a component with an analysis_imp and you want to make that 'imp' available at the agent's interface level. In this situation you declare and instantiate the analysis_export in the agent class, then in the connect_phase connect the agent's analysis_export to your internal component's analysis_imp.

Its worth noting, exports are for the subscribing side, but on the publishing side regular uvm_analysis_port's can be used in the same way. So agent's can instantiate analysis_ports and connect them to an internal component's analysis_port.

This is good because it allows you to avoid reaching down into the hierarchy when you are connecting components (which makes maintenance easier):

bad:

bus_agent.internal_monitor.packet_port.connect(checker.ref_model.packet_imp) 

good:

bus_agent.packet_port.connect(checker.packet_export) 

Its also good to become familiar with the macro uvm_analysis_imp_decl(). It allows you to use more than one analysis_imp in a component.

4

Advantage for this analysis port is that a user can transfer data from a single producer to multiple consumers that is not archived with help of uvm_blocking_put_port.

This thing is also explained in the figure.

Here I provides sample code to get more clarity for uvm_analysis_port.

Remember: Port connection is used to connect two or more independent component.

This image gives explanation of uvm_analysis_port

uvm_analysis_port EXAMPLE

class transaction extends uvm_sequence_item; `uvm_object_utils(transaction); rand int unsigned a; rand int unsigned b; function new(string name =""); super.new(name); endfunction endclass class producer extends uvm_component; `uvm_component_utils(producer); transaction tr_inst; uvm_analysis_port #(transaction) produce_to_consumer_p; function new(string name ="",uvm_component parent); super.new(name,parent); produce_to_consumer_p = new("produce_to_consumer_p",this); tr_inst = new("tr_inst"); endfunction task run_phase(uvm_phase phase); super.run_phase(phase); phase.raise_objection(this); // tr_inst.randomize(); `uvm_info(get_full_name(),"Write the data from PRODUCER",UVM_LOW); tr_inst.a = 10; tr_inst.b = 20; produce_to_consumer_p.write(tr_inst); phase.drop_objection(this); endtask endclass class consumer_1 extends uvm_component; `uvm_component_utils(consumer_1); uvm_analysis_imp#(transaction,consumer_1) write_imp_1; function new(string name ="",uvm_component parent); super.new(name,parent); write_imp_1 = new("write_imp_1",this); endfunction function void write(transaction tr_inst); `uvm_info(get_full_name(),"Got the data in CONSUMER_1",UVM_LOW); `uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW); endfunction endclass class consumer_2 extends uvm_component; `uvm_component_utils(consumer_2); uvm_analysis_imp#(transaction,consumer_2) write_imp_2; function new(string name ="",uvm_component parent); super.new(name,parent); write_imp_2 = new("write_imp_2",this); endfunction function void write(transaction tr_inst); `uvm_info(get_full_name(),"Got the data in CONSUMER_2",UVM_LOW); `uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW); endfunction endclass class consumer_3 extends uvm_component; `uvm_component_utils(consumer_3); uvm_analysis_imp#(transaction,consumer_3) write_imp_3; function new(string name ="",uvm_component parent); super.new(name,parent); write_imp_3 = new("write_imp_3",this); endfunction function void write(transaction tr_inst); `uvm_info(get_full_name(),"Got the data in CONSUMER_3",UVM_LOW); `uvm_info(get_full_name(),$sformatf("The value of a = %0d and b = %0d",tr_inst.a,tr_inst.b),UVM_LOW); endfunction endclass class env extends uvm_component; `uvm_component_utils(env); producer p_inst; consumer_1 c_inst_1; consumer_2 c_inst_2; consumer_3 c_inst_3; function new(string name="",uvm_component parent); super.new(name,parent); p_inst = new("p_inst",this); c_inst_1 = new("c_inst_1",this); c_inst_2 = new("c_inst_2",this); c_inst_3 = new("c_inst_3",this); endfunction function void connect(); p_inst.produce_to_consumer_p.connect(c_inst_1.write_imp_1); p_inst.produce_to_consumer_p.connect(c_inst_2.write_imp_2); p_inst.produce_to_consumer_p.connect(c_inst_3.write_imp_3); endfunction endclass module main(); env env_inst; initial begin env_inst = new("env_inst",null); run_test(); end endmodule 

Here is link which gives you more clarity for analysis port as well as uvm_port.

Link:

0

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like