TLM FIFO Nonblocking example

TLM FIFO with NonBlocking ports

TLM FIFO Nonblocking port
TLM FIFO Nonblocking port

In this example, Nonblocking ports are used to put and get the transactions to and from the TLM FIFO.

TLM TesetBench Components are,

————————————————————–
Name                              Type
————————————————————–
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
trans_out               uvm_nonblocking_put_port
comp_b                     component_b
trans_in                 uvm_nonblocking_get_port
fifo_ab                       uvm_tlm_fifo #(T)
get_ap                   uvm_analysis_port
get_peek_export   uvm_get_peek_imp
put_ap                   uvm_analysis_port
put_export             uvm_put_imp
————————————————————–

Implementing port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaraing the put port
  uvm_nonblocking_put_port#(transaction) trans_out;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this); //Step-2. Creating the port
  endfunction : new
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    #100;
    
    trans = transaction::type_id::create("trans", this);
    void'(trans.randomize());
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
    
    //Step-3. Calling put method to push transaction to TLM FIFO
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.try_put(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

As the port is nonblocking, try_put method is used to put trans to FIFO.

Implementing port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaraing the get port 
  uvm_nonblocking_get_port#(transaction) trans_in; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Create the port
  endfunction : new
  
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    //#200; To execute try_get after try_put
    
    if(trans_in.can_get()) begin //{   //Step-3. Checking is FIFO can send the packet
      `uvm_info(get_type_name(),$sformatf(" Before calling port get method"),UVM_LOW)
      void'(trans_in.try_get(trans));  //Step-4. Get the transaction from TLM FIFO
      `uvm_info(get_type_name(),$sformatf(" After  calling port get method"),UVM_LOW)
      `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                            trans.sprint()),UVM_LOW)
    end //}
    else begin //{
      `uvm_info(get_type_name(),$sformatf(" No entry,
                                            not able to get the trans"),UVM_LOW)
    end //}
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_b

As the port is nonblocking, the can_get and try_get method is used to get trans to FIFO.

Implementing TLM FIFO in env

Below are the steps to implement TLM FIFO,

  1. Declare the TLM FIFO
  2. Create the FIFO
  3. Connect the TLM FIFO put_export with producer port
  4. Connect the TLM FIFO get_export with consumer port
class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  component_a comp_a;
  component_b comp_b;
  
  //Step-1. Declaring the TLM FIFO
  uvm_tlm_fifo #(transaction) fifo_ab;
  
  `uvm_component_utils(environment)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction : new
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    comp_a = component_a::type_id::create("comp_a", this);
    comp_b = component_b::type_id::create("comp_b", this);
    
    //Step-2. Creating the FIFO
    fifo_ab = new("fifo_ab", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    
    //Step-3. Connecting FIFO put_export with producer port
    comp_a.trans_out.connect(fifo_ab.put_export);
    //Step-4. Connecting FIFO get_export with consumer port
    comp_b.trans_in.connect(fifo_ab.get_export);
  endfunction : connect_phase
endclass : environment

Simulator Output can_get() method executed before the try_put();

#100 delay added before the randomize() and try_put() method, which leads to execution of can_get() before try_put(). this leads to can_get() returing 0. So try_get() will not get excuted.

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------------
Name Type Size Value
------------------------------------------------------------
uvm_test_top basic_test - @1840
 env environment - @1909
 comp_a component_a - @1941
 trans_out uvm_nonblocking_put_port - @1976
 comp_b component_b - @2009
 trans_in uvm_nonblocking_get_port - @2044
 fifo_ab uvm_tlm_fifo #(T) - @2010
 get_ap uvm_analysis_port - @2214
 get_peek_export uvm_get_peek_imp - @2144
 put_ap uvm_analysis_port - @2179
 put_export uvm_put_imp - @2109
------------------------------------------------------------
UVM_INFO component_b.sv(35) @ 0: uvm_test_top.env.comp_b [component_b] No entry, not able to get the trans
UVM_INFO component_a.sv(31) @ 100: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(32) @ 100: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2286
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_a.sv(34) @ 100: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_a.sv(36) @ 100: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 100: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 100: reporter [UVM/REPORT/SERVER]

 Simulator Output  can_get() method executed after the try_put();

Adding #200 delay before can_get() method, which leads to returning 1 on calling can_get().

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------------
Name Type Size Value
------------------------------------------------------------
uvm_test_top basic_test - @1840
 env environment - @1909
 comp_a component_a - @1941
 trans_out uvm_nonblocking_put_port - @1976
 comp_b component_b - @2009
 trans_in uvm_nonblocking_get_port - @2044
 fifo_ab uvm_tlm_fifo #(T) - @2010
 get_ap uvm_analysis_port - @2214
 get_peek_export uvm_get_peek_imp - @2144
 put_ap uvm_analysis_port - @2179
 put_export uvm_put_imp - @2109
------------------------------------------------------------
UVM_INFO component_a.sv(31) @ 100: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(32) @ 100: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_a.sv(34) @ 100: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_a.sv(36) @ 100: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO component_b.sv(29) @ 200: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_b.sv(31) @ 200: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO component_b.sv(32) @ 200: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 200: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 200: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯