Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference Between the uvm_analysis ports

Tags:

uvm

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:

  • https://verificationacademy.com/forums/uvm/uvmanalysisimp-and-uvmanalysisexport
  • https://www.vmmcentral.org/uvm_vmm_ik/files3/tlm1/uvm_analysis_port-svh.html

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

like image 972
haykp Avatar asked Mar 01 '16 05:03

haykp


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.

like image 81
Ashley Winn Avatar answered Sep 19 '22 01:09

Ashley Winn


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: http://stackoverflow.com/questions/38085875/where-to-use-uvm-blocking-put-port-and-uvm-analysis-port

like image 41
Ashutosh Rawal Avatar answered Sep 21 '22 01:09

Ashutosh Rawal