Tutorials

Learn More

uvm_analysis multiple ports and single imp diagram
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "seq_item.sv"

class producer_A extends uvm_component;
  seq_item req;
  uvm_analysis_port #(seq_item) a_put;
  
  `uvm_component_utils(producer_A)
  
  function new(string name = "producer_A", uvm_component parent = null);
    super.new(name, parent);
    a_put = new("a_put", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    
    req = seq_item::type_id::create("req");
    assert(req.randomize());
    `uvm_info(get_type_name(), $sformatf("Send value = %0h", req.value), UVM_NONE);
    a_put.write(req);
  endtask
endclass

class producer_B extends uvm_component;
  seq_item req;
  uvm_analysis_port #(seq_item) a_put;
  
  `uvm_component_utils(producer_B)
  
  function new(string name = "producer_B", uvm_component parent = null);
    super.new(name, parent);
    a_put = new("a_put", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    
    req = seq_item::type_id::create("req");
    assert(req.randomize());
    `uvm_info(get_type_name(), $sformatf("Send value = %0h", req.value), UVM_NONE);
    a_put.write(req);
  endtask
endclass
//---------------------------------------------------------------------------------
// Define analysis_imp port
`uvm_analysis_imp_decl(_PORT_A)
`uvm_analysis_imp_decl(_PORT_B)
class consumer extends uvm_component;
  seq_item req;
  // Declare analysis_imp port
  uvm_analysis_imp_PORT_A #(seq_item, consumer) analysis_imp_A;
  uvm_analysis_imp_PORT_B #(seq_item, consumer) analysis_imp_B;
  
  `uvm_component_utils(consumer)
  
  function new(string name = "consumer", uvm_component parent = null);
    super.new(name, parent);
    // Create analysis_imp port
    analysis_imp_A = new("analysis_imp_A", this);
    analysis_imp_B = new("analysis_imp_B", this);
  endfunction
  
  // write methods implementation
  virtual function void write_PORT_A(seq_item req);
    `uvm_info(get_type_name(), $sformatf("PORT A: Received value = %0h", req.value), UVM_NONE);
  endfunction
  
  virtual function void write_PORT_B(seq_item req);
    `uvm_info(get_type_name(), $sformatf("PORT B: Received value = %0h", req.value), UVM_NONE);
  endfunction
endclass

class env extends uvm_env;
  producer_A pro_A;
  producer_B pro_B;
  consumer con;
  `uvm_component_utils(env)
  
  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    pro_A = producer_A::type_id::create("pro_A", this);
    pro_B = producer_B::type_id::create("pro_B", this);
    con = consumer::type_id::create("con", this);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    pro_A.a_put.connect(con.analysis_imp_A);
    pro_B.a_put.connect(con.analysis_imp_B);
  endfunction
endclass
              
class test extends uvm_test;
  env env_o;
  `uvm_component_utils(test)
  
  function new(string name = "test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env_o = env::type_id::create("env_o", this);
  endfunction
 
  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    #50;
    phase.drop_objection(this);
  endtask
endclass

module tb_top;
  initial begin
    run_test("test");
  end
endmodule

Output:

UVM_INFO testbench.sv(43) @ 0: uvm_test_top.env_o.pro_B [producer_B] Send value = c
UVM_INFO testbench.sv(72) @ 0: uvm_test_top.env_o.con [consumer] PORT B: Received value = c
UVM_INFO testbench.sv(22) @ 0: uvm_test_top.env_o.pro_A [producer_A] Send value = 2
UVM_INFO testbench.sv(68) @ 0: uvm_test_top.env_o.con [consumer] PORT A: Received value = 2