Contact / Report an issue

TLM FIFO Nonblocking example

TLM FIFO with NonBlocking ports

TLM FIFO Nonblocking port
TLM FIFO Nonblocking port

* Click on image for a better view

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]

Execute the above code on