Tutorials

Learn More

The consumer controls the flow of transactions. All methods get(), try_get and can_get have to be implemented in the producer, and method calls need to be called from the consumer.

Imp port has an implementation of the method.

uvm_get_port/ imp using int

uvm_get_port imp using int diagram
`include "uvm_macros.svh"
import uvm_pkg::*;

class producer extends uvm_component;
  uvm_get_imp#(int, producer) tlm_imp;
  
  `uvm_component_utils(producer)
  
  function new(string name = "producer", uvm_component parent = null);
    super.new(name, parent);
    tlm_imp = new("tlm_imp", this);
  endfunction
  
  virtual task get(output int val);
    val = 10;
    `uvm_info(get_type_name(), $sformatf("Sending value = %0h", val), UVM_NONE);
  endtask
  
  virtual function bit try_get(int val);
    `uvm_info(get_type_name(), $sformatf("Sending try_put value = %0h", val), UVM_NONE);
    return 1;
  endfunction
  
  virtual function bit can_get();
    `uvm_info(get_type_name(), "inside can_get", UVM_NONE);
    return 1;
  endfunction
endclass

class consumer extends uvm_component;
  uvm_get_port #(int) tlm_get;
   
  `uvm_component_utils(consumer)
  
  function new(string name = "consumer", uvm_component parent = null);
    super.new(name, parent);
    tlm_get = new("tlm_get", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    int value;
    super.run_phase(phase);
    
    tlm_get.get(value);
    `uvm_info(get_type_name(), $sformatf("Receive value = %0h", value), UVM_NONE);
    tlm_get.try_get(value);
    `uvm_info(get_type_name(), $sformatf("try_get value = %0h", value), UVM_NONE);
    tlm_get.can_get();
  endtask
endclass

class env extends uvm_env;
  producer pro;
  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 = producer::type_id::create("pro", this);
    con = consumer::type_id::create("con", this);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    con.tlm_get.connect(pro.tlm_imp);
    //pro.tlm_imp.connect(con.tlm_get); imp to port connect is not valid
  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(16) @ 0: uvm_test_top.env_o.pro [producer] Sending value = a
UVM_INFO testbench.sv(45) @ 0: uvm_test_top.env_o.con [consumer] Receive value = a
UVM_INFO testbench.sv(20) @ 0: uvm_test_top.env_o.pro [producer] Sending try_put value = 0
UVM_INFO testbench.sv(47) @ 0: uvm_test_top.env_o.con [consumer] try_get value = 0
UVM_INFO testbench.sv(25) @ 0: uvm_test_top.env_o.pro [producer] inside can_get

Similar to uvm_get_port/ imp using transaction, instead of passing int datatype, transaction class handle can also be passed.

uvm_blocking_get_port/ imp using transaction item

uvm_blocking_get_port imp using transaction diagram

seq_item used in below two examples

class seq_item extends uvm_sequence_item;
  rand bit [3:0] value;
  `uvm_object_utils(seq_item)
  
  function new(string name = "seq_item");
    super.new(name);
  endfunction
endclass
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "seq_item.sv"

class producer extends uvm_component;
  seq_item req;
  uvm_blocking_get_imp #(seq_item, producer) tlm_imp;
  
  `uvm_component_utils(producer)
  
  function new(string name = "producer", uvm_component parent = null);
    super.new(name, parent);
    tlm_imp = new("tlm_imp", this);
  endfunction
  
  virtual task get(output seq_item req);
    req = seq_item::type_id::create("req");
    assert(req.randomize());
    `uvm_info(get_type_name(), $sformatf("Send value = %0h", req.value), UVM_NONE);
  endtask
endclass

class consumer extends uvm_component;
  seq_item req;
  uvm_blocking_get_port #(seq_item) tlm_get;
  
  `uvm_component_utils(consumer)
  
  function new(string name = "consumer", uvm_component parent = null);
    super.new(name, parent);
    tlm_get = new("tlm_get", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    tlm_get.get(req);
    `uvm_info(get_type_name(), $sformatf("Received value = %0h", req.value), UVM_NONE);
  endtask
  
endclass

class env extends uvm_env;
  producer pro;
  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 = producer::type_id::create("pro", this);
    con = consumer::type_id::create("con", this);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    con.tlm_get.connect(pro.tlm_imp);
  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(20) @ 0: uvm_test_top.env_o.pro [producer] Send value = 0
UVM_INFO testbench.sv(38) @ 0: uvm_test_top.env_o.con [consumer] Received value = 0

uvm_nonblocking_get_port/ imp using transaction item

uvm_nonblocking_get_port imp using transaction diagram
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "seq_item.sv"

class producer extends uvm_component;
  seq_item req;
  uvm_nonblocking_get_imp #(seq_item, producer) tlm_imp;
  
  `uvm_component_utils(producer)
  
  function new(string name = "producer", uvm_component parent = null);
    super.new(name, parent);
    tlm_imp = new("tlm_imp", this);
  endfunction
  
  virtual function bit try_get(output seq_item req);
    req = seq_item::type_id::create("req");
    assert(req.randomize());
    `uvm_info(get_type_name(), $sformatf("Send value = %0h", req.value), UVM_NONE);
    return 1;
  endfunction
  
  virtual function bit can_get();
  endfunction
endclass

class consumer extends uvm_component;
  seq_item req;
  uvm_nonblocking_get_port #(seq_item) tlm_get;
  
  `uvm_component_utils(consumer)
  
  function new(string name = "consumer", uvm_component parent = null);
    super.new(name, parent);
    tlm_get = new("tlm_get", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    if(tlm_get.try_get(req)) begin
      `uvm_info(get_type_name(), $sformatf("Received value = %0h", req.value), UVM_NONE);
    end
    else begin
      `uvm_info(get_type_name(), "try_get failed", UVM_NONE);
    end
  endtask
  
endclass

class env extends uvm_env;
  producer pro;
  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 = producer::type_id::create("pro", this);
    con = consumer::type_id::create("con", this);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    con.tlm_get.connect(pro.tlm_imp);
  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(20) @ 0: uvm_test_top.env_o.pro [producer] Send value = b
UVM_INFO testbench.sv(42) @ 0: uvm_test_top.env_o.con [consumer] Received value = b