Tutorials

Learn More

TLM Fifo nonblocking block diagram
`include "uvm_macros.svh"
import uvm_pkg::*;

`include "seq_item.sv"

class producer extends uvm_component;
  seq_item req;
  uvm_nonblocking_put_port #(seq_item) tlm_put;
  
  `uvm_component_utils(producer)
  
  function new(string name = "producer", uvm_component parent = null);
    super.new(name, parent);
    tlm_put = new("tlm_put", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    
    repeat(10) begin
      if(tlm_put.can_put) begin
        req = seq_item::type_id::create("req");
        assert(req.randomize());
        tlm_put.try_put(req);
        `uvm_info(get_name(), $sformatf("Send value = %0h", req.value), UVM_NONE);
        #5;
      end
    end
  endtask
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);
    
    repeat(10) begin
      #10;
      if(tlm_get.can_get) begin
        tlm_get.try_get(req);
        `uvm_info(get_name(), $sformatf("Received value = %0h", req.value), UVM_NONE);
      end
      else `uvm_info(get_name(), "can_get failed: can not retrieve transaction", UVM_NONE);
    end
  endtask
endclass

class env extends uvm_env;
  uvm_tlm_fifo #(seq_item) tlm_fifo;
  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);
    
    tlm_fifo = new("tlm_fifo", this, 3);
    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);
    pro.tlm_put.connect(tlm_fifo.put_export);
    con.tlm_get.connect(tlm_fifo.get_export);
  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);
    
    fork begin
      while(1) begin
        if(env_o.tlm_fifo.is_empty) `uvm_info(get_name(), "UVM_TLM_FIFO is empty", UVM_LOW);
        if(env_o.tlm_fifo.is_full) `uvm_info(get_name(), "UVM_TLM_FIFO is full", UVM_LOW);
        `uvm_info(get_name(), $sformatf("UVM_TLM_FIFO size = %0d, used = %0d", env_o.tlm_fifo.size(), env_o.tlm_fifo.used()), UVM_LOW);
        #5;
      end
    end
    begin
      #30;
      if(env_o.tlm_fifo.is_full) begin
        `uvm_info(get_name(), $sformatf("Before flush: UVM_TLM_FIFO used = %0d, is_empty = %0d", env_o.tlm_fifo.used, env_o.tlm_fifo.is_empty), UVM_LOW);
        env_o.tlm_fifo.flush();
        `uvm_info(get_name(), $sformatf("After flush: UVM_TLM_FIFO used = %0d, is_empty = %0d", env_o.tlm_fifo.used, env_o.tlm_fifo.is_empty), UVM_LOW);
      end
    end
    join_any
    disable fork;
    phase.drop_objection(this);
  endtask
endclass

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

Output:

UVM_INFO testbench.sv(100) @ 0: uvm_test_top [uvm_test_top] UVM_TLM_FIFO is empty
UVM_INFO testbench.sv(102) @ 0: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 0
UVM_INFO testbench.sv(25) @ 0: uvm_test_top.env_o.pro [pro] Send value = 5
UVM_INFO testbench.sv(102) @ 5: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 1
UVM_INFO testbench.sv(25) @ 5: uvm_test_top.env_o.pro [pro] Send value = 8
UVM_INFO testbench.sv(50) @ 10: uvm_test_top.env_o.con [con] Received value = 5
UVM_INFO testbench.sv(102) @ 10: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 1
UVM_INFO testbench.sv(25) @ 10: uvm_test_top.env_o.pro [pro] Send value = 2
UVM_INFO testbench.sv(102) @ 15: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 2
UVM_INFO testbench.sv(25) @ 15: uvm_test_top.env_o.pro [pro] Send value = 6
UVM_INFO testbench.sv(50) @ 20: uvm_test_top.env_o.con [con] Received value = 8
UVM_INFO testbench.sv(102) @ 20: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 2
UVM_INFO testbench.sv(25) @ 20: uvm_test_top.env_o.pro [pro] Send value = b
UVM_INFO testbench.sv(101) @ 25: uvm_test_top [uvm_test_top] UVM_TLM_FIFO is full
UVM_INFO testbench.sv(102) @ 25: uvm_test_top [uvm_test_top] UVM_TLM_FIFO size = 3, used = 3
UVM_INFO testbench.sv(109) @ 30: uvm_test_top [uvm_test_top] Before flush: UVM_TLM_FIFO used = 3, is_empty = 0
UVM_INFO testbench.sv(111) @ 30: uvm_test_top [uvm_test_top] After flush: UVM_TLM_FIFO used = 0, is_empty = 1
UVM_INFO testbench.sv(52) @ 30: uvm_test_top.env_o.con [con] can_get failed: can not retrieve transaction