TLM FIFO Example

TLM FIFO

TLM FIFO Example
TLM FIFO Example

The TLM FIFO provides storage for the transactions between the two independently running processes.

  • FIFO can be used as a buffer between the producer and consumer
  • TLM FIFO consists of put and get methods
  • Producer port is connected to the put_export of the FIFO
  • Consumer port is connected to the get_export of the FIFO

TLM TesetBench Components are,

————————————————————–
Name                              Type
————————————————————–
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
trans_out               uvm_blocking_put_port
comp_b                     component_b
trans_in                 uvm_blocking_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_blocking_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);
    
    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.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

Implementing port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaraing the get port 
  uvm_blocking_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);
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port get method"),UVM_LOW)
    trans_in.get(trans);  //Step-3. 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)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_b

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

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_blocking_put_port - @1976
 comp_b component_b - @2009
 trans_in uvm_blocking_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(26) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1883
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_a.sv(32) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_a.sv(34) @ 0: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1883
 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) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

Non blocking can_get method implementation

Nonblocking can_get method

NonBlocking Get Port Imp port
NonBlocking Get Port Imp port

This example is a continuation of the previous example with the can_get method implemented.

Before calling the trans_in.try_get() method comp_b checks for the comp_a status by calling trans_in.can_get() method. On calling trans_in.can_get() comp_a can respond with 1 if it’s ready to send the transaction packet, otherwise 0.

In order to add can_get() method, there are two additional steps on top of steps followed in the previous example.

1. In comp_b before calling the try_get method, Call can_get() method and check for the comp_a status

if(trans_in.can_get) begin //{
    
  `uvm_info(get_type_name(),$sformatf(" component_a can send the transaction"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Requesting transaction."),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Before calling port get method"),UVM_LOW)
  
  if(trans_in.try_get(trans)) begin //{
    `uvm_info(get_type_name(),$sformatf(" recived transaction
                                          from 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(" Not recived transaction
                                          from get method"),UVM_LOW)
  end //}
      
  `uvm_info(get_type_name(),$sformatf(" After  calling port get method"),UVM_LOW)
end //}
else begin //{
  `uvm_info(get_type_name(),$sformatf(" component_a is not ready to send
                                        the transaction"),UVM_LOW)
end //}

2. Implement the can_get() method in comp_a

virtual function bit can_get();
  `uvm_info(get_type_name(),$sformatf(" component_b requested for status"),UVM_LOW)
  return 0;
endfunction

Simulator Output With can_get() return value 1.

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335 
 env environment - @348 
 comp_a component_a - @357 
 trans_out uvm_nonblocking_get_imp - @366 
 comp_b component_b - @376 
 trans_in uvm_nonblocking_get_port - @385 
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Checking component_a status to get the transaction
UVM_INFO component_a.sv(40) @ 0: uvm_test_top.env.comp_a [component_a] component_b requested for status
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] component_a can send the transaction
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(31) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @418 
 addr integral 4 'h3 
 wr_rd integral 1 'h1 
 wdata integral 8 'h6 
---------------------------------

UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] recived transaction from get method
UVM_INFO component_b.sv(35) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @418 
 addr integral 4 'h3 
 wr_rd integral 1 'h1 
 wdata integral 8 'h6 
---------------------------------

UVM_INFO component_b.sv(41) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE] 
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Simulator Output With can_get() return value 0.

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335 
 env environment - @348 
 comp_a component_a - @357 
 trans_out uvm_nonblocking_get_imp - @366 
 comp_b component_b - @376 
 trans_in uvm_nonblocking_get_port - @385 
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Checking component_a status to get the transaction
UVM_INFO component_a.sv(40) @ 0: uvm_test_top.env.comp_a [component_a] component_b requested for status
UVM_INFO component_b.sv(45) @ 0: uvm_test_top.env.comp_b [component_b] component_a is not ready to send the transaction
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE] 
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

Output Analysist

In the second output with the return value set to ‘0’, we can see that as the return value is ‘0’ from comp_a, uvm_infos before and after the try_get method of comp_b and uvm_infos inside try_get method of comp_a are not getting executed.
❮ Previous Next ❯

NonBlocking TLM Get port imp port

Nonblocking TLM port and Imp Port

NonBlocking Get Port Get Imp Port
NonBlocking Get Port Get Imp Port

This example shows how to declare, create and connect the TLM non-blocking get ports, implementing and using the TLM non-blocking get methods. In this example blocking ports of the previous example ( TLM Get ports and imp_ports ) are replaced with the non-blocking get ports. It is preferred to refer to TLM Get ports and imp_ports example before going through this example.

TLM TesetBench Components are,

———————————————————-
Name                    Type
———————————————————-
uvm_test_top        basic_test
env                    environment
comp_a         component_a
trans_out   uvm_nonblocking_get_imp
comp_b         component_b
trans_in     uvm_nonblocking_get_port
———————————————————-

Declare and Create TLM Get Port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring 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. Creating the port
  endfunction : new
  
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    `uvm_info(get_type_name(),$sformatf(" Requesting transaction."),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port get method"),UVM_LOW)
    
    //Step-3. Calling try_get to receive the transaction
    if(trans_in.try_get(trans)) begin //{
      `uvm_info(get_type_name(),$sformatf(" recived transaction
                                            from get method"),UVM_LOW)
      `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                            trans.sprint()),UVM_LOW)
    end //}
    else
      `uvm_info(get_type_name(),$sformatf(" Not recived transaction
                                            from get method"),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" After  calling port get method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
  
endclass : component_b

try_get() method is used to receive the transaction form comp_b. try_get() methods returns ‘1’ on successful receive of transaction, otherwise ‘0’.

Declare and Create TLM Imp_port in comp_a

class component_a extends uvm_component;
  
  uvm_nonblocking_get_imp#(transaction,component_a) trans_out; //Step-1: Declare get Imp_port
  
  `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. Create the port
  endfunction : new
  //---------------------------------------
  // Imp port try_get method
  //---------------------------------------
  //Step-3. try_get method to send trans to comp_b
  virtual function bit try_get(output transaction trans);
    
    `uvm_info(get_type_name(),$sformatf(" Recived transaction
                                          imp port get request"),UVM_LOW)
    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)
    `uvm_info(get_type_name(),$sformatf(" Sendting trans packet"),UVM_LOW)
    
    return 1;
  endfunction
  
  //---------------------------------------
  // Imp port can_get method
  //---------------------------------------
  //Setp-4: can_get() method.
  virtual function bit can_get();
  endfunction
endclass : component_a

Note:
As the port is nonblocking, methods should be implemented as function not task.

* Implementing and using of can_put is shown in the next example

Connecting TLM Port and Imp Port in env

function void connect_phase(uvm_phase phase);
  comp_b.trans_in.connect(comp_a.trans_out); //Connecting the ports
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @335 
 env environment - @348 
 comp_a component_a - @357 
 trans_out uvm_nonblocking_get_imp - @366 
 comp_b component_b - @376 
 trans_in uvm_nonblocking_get_port - @385 
------------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @412 
 addr integral 4 'h3 
 wr_rd integral 1 'h1 
 wdata integral 8 'h6 
---------------------------------

UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(31) @ 0: uvm_test_top.env.comp_b [component_b] recived transaction from get method
UVM_INFO component_b.sv(32) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @412 
 addr integral 4 'h3 
 wr_rd integral 1 'h1 
 wdata integral 8 'h6 
---------------------------------

UVM_INFO component_b.sv(37) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE] 
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

The next example shows the implementation of the try_put() method.
❮ Previous Next ❯

TLM Get port imp port

Connecting TLM Get port imp port

TLM Get Port Get Imp port
TLM Get Port Get Imp port

This example shows connection TLM get port and get imp port.

In the components with TLM put ports,

  • The producer component initiates the transaction and sends it to consumer component
  • The producer component will be implemented with TLM put port and Consumer component with TLM imp_port
  • put method has to be implemented in the consumer

Whereas in with TLM get ports,

  • The consumer component will request for the transaction
  • The consumer component will be implemented with TLM get port and Producer with TLM imp_port
  • get method has to be implemented in the producer

Below are the steps to implement a TLM get port between comp_a and comp_b.

  1. Declare and Create TLM Get Port in comp_b
  2. Declare and Create TLM Imp Port in comp_a
  3. Connect TLM Port and Imp Port in env
  4. Call interface method in comp_b to get the transaction
  5. Implement an interface method in comp_a to randomize and send the transaction

TLM Get port TesetBench Components are,

—————————————————————
Name                Type
—————————————————————
uvm_test_top              basic_test
env                          environment
comp_a                 component_a
trans_out           uvm_blocking_get_imp
comp_b                 component_b
trans_in             uvm_blocking_get_port
—————————————————————

Implementing TLM get port in comp_b (Consumer)

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring TLM Get port
  uvm_blocking_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. Creating port
  endfunction : new
  
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    `uvm_info(get_type_name(),$sformatf(" Requesting transaction."),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port get method"),UVM_LOW)
    //Step-3. Calling TLM get mehtod to recieve transaction from comp_a
    trans_in.get(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port get method"),UVM_LOW)
    trans.print();
    
    phase.drop_objection(this);
  endtask : run_phase
  
endclass : component_b

Implementing TLM get imp port in comp_a (Producer)

class component_a extends uvm_component;
  //Step-1. Declaring TLM Get Imp_port 
  uvm_blocking_get_imp#(transaction,component_a) 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 port
  endfunction : new
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  //Step-3. Get Method, randomize and send the trans to comp_b
  virtual task get(output transaction trans);
    
    `uvm_info(get_type_name(),$sformatf(" Recived transaction imp port
                                          get request"),UVM_LOW)
    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)
    `uvm_info(get_type_name(),$sformatf(" Sendting trans packet"),UVM_LOW)
  endtask
endclass : component_a

Connecting get port with get imp port in env

function void connect_phase(uvm_phase phase);
  comp_b.trans_in.connect(comp_a.trans_out); //Connecting port with imp_port
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
---------------------------------------------------
Name Type Size Value
---------------------------------------------------
uvm_test_top basic_test - @1839
 env environment - @1908
 comp_a component_a - @1940
 trans_out uvm_blocking_get_imp - @1975
 comp_b component_b - @2008
 trans_in uvm_blocking_get_port - @2043
---------------------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.env.comp_b [component_b] Requesting transaction.
UVM_INFO component_b.sv(28) @ 0: uvm_test_top.env.comp_b [component_b] Before calling port get method
UVM_INFO component_a.sv(24) @ 0: uvm_test_top.env.comp_a [component_a] Recived transaction imp port get request
UVM_INFO component_a.sv(28) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
 addr integral 4 'ha 
 wr_rd integral 1 'h0 
 wdata integral 8 'h57 
---------------------------------

UVM_INFO component_a.sv(31) @ 0: uvm_test_top.env.comp_a [component_a] Sendting trans packet
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] After calling port get method
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
 addr integral 4 'ha 
 wr_rd integral 1 'h0 
 wdata integral 8 'h57 
---------------------------------
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

Non blocking can_put method implementation

Nonblocking can_put method

can_put method
can_put method

This example is a continuation of the previous example with the can_put method implemented.

Before calling the trans_out.try_put() method comp_a checks for the comp_b status by calling trans_out.can_put() method. On calling trans_out.can_put() comp_b can respond with 1 if it’s ready to accept the transaction packet, otherwise 0.

In order to add can_put() method, there are two additional steps on top of steps followed in the previous example.

1. In comp_a before calling the try_put method, Call can_put() method and check for the comp_b status

if(trans_out.can_put) begin //{
  `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)
end //}
else
  `uvm_info(get_type_name(),$sformatf(" component_b is not ready to accept the packet"),UVM_LOW)

2. Implement the can_put() method in comp_b

virtual function bit can_put();
  `uvm_info(get_type_name(),$sformatf(" Inside can_put method"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Sending can_put status as 1"),UVM_LOW)
  return 1;   
endfunction

Simulator Output With can_put() return value 1.

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
 env environment - @1908
 comp_a component_a - @1940
 trans_out uvm_nonblocking_put_port - @1975
 comp_b component_b - @2008
 trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: 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_b.sv(33) @ 0: uvm_test_top.env.comp_b [component_b] Inside can_put method
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] Sending can_put status as 1
UVM_INFO component_a.sv(33) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside try_put method
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
UVM_INFO component_b.sv(26) @ 0: 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 component_a.sv(35) @ 0: 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) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Simulator Output With can_put() return value 0.

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
 env environment - @1908
 comp_a component_a - @1940
 trans_out uvm_nonblocking_put_port - @1975
 comp_b component_b - @2008
 trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: 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_b.sv(33) @ 0: uvm_test_top.env.comp_b [component_b] Inside can_put method
UVM_INFO component_b.sv(34) @ 0: uvm_test_top.env.comp_b [component_b] Sending can_put status as 1
UVM_INFO component_a.sv(38) @ 0: uvm_test_top.env.comp_a [component_a] component_b is not ready to accept the packet
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

Output Analysis

In the second output with the return value set to ‘0’, we can see that as the return value is ‘0’ from comp_b, uvm_infos before and after the try_put method of comp_a and uvm_infos inside try_put method of comp_b are not getting executed.
❮ Previous Next ❯

Non Blocking TLM port Imp port connection

Nonblocking TLM port and Imp Port

NonBlocking Port Imp Port
NonBlocking Port Imp Port

This example shows how to declare, create and connect the TLM non-blocking ports, implementing and using the TLM non-blocking methods. In this example blocking ports of the previous example (Connecting TLM Port and Imp Port) are replaced with the non-blocking ports. It is preferred to refer to Connecting TLM Port and Imp Port example before going through this example.

Below are the steps to implement a TLM Communication mechanism between comp_a and comp_b.

  • Declare and Create TLM Port in comp_a
  • Declare and Create TLM Imp Port in comp_b
  • Connect TLM Port and Imp Port in env
  • Call interface method in comp_a to send the transaction
  • Implement interface methods in comp_b to receive the transaction

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_put_imp
———————————————————-

Declare and Create TLM Port in comp_a

class component_a extends uvm_component;
  //Step-1. Declaring Non-blocking 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);
  endtask : run_phase
endclass : component_a

Declare and Create TLM Port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring nonblocking put imp port
  uvm_nonblocking_put_imp #(transaction,component_b) 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. Creating the port
  endfunction : new
endclass : component_b

Connect TLM Port and Imp Port in env

function void connect_phase(uvm_phase phase);
  //Step-1, Connecting the ports
  comp_a.trans_out.connect(comp_b.trans_in);
endfunction : connect_phase

Call interface method in comp_a to send the transaction

As the port declared is a nonblocking port, the try_put method has to be used for sending the transaction packet.

void'(trans.randomize());
trans_out.try_put(trans);

Implement an interface method in comp_b to receive the transaction

1. In order to receive the transaction on nonblocking imp port try_put and can_put methods has to be implemented.

Note:
As the port is nonblocking, methods should be implemented as function not task.

In the blocking example, the put method is implemented as a task.

virtual function try_put(transaction trans);
  `uvm_info(get_type_name(),$sformatf(" Inside try_put method"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)
endfunction
virtual function bit can_put();
endfunction

* Implementing and using of can_put is shown in the next example

2. Complete comp_b code

class component_b extends uvm_component;
  
  transaction trans;
  uvm_nonblocking_put_imp#(transaction,component_b) 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);
  endfunction : new
  
  //---------------------------------------
  // Imp port try_put method
  //---------------------------------------
  virtual function bit try_put(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside try_put method"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)
  endfunction
  
  //---------------------------------------
  // Imp port can_put method
  //---------------------------------------
  virtual function bit can_put();
  endfunction
endclass : component_b

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1839
 env environment - @1908
 comp_a component_a - @1940
 trans_out uvm_nonblocking_put_port - @1975
 comp_b component_b - @2008
 trans_in uvm_nonblocking_put_imp - @2043
------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: 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(32) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside try_put method
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
UVM_INFO component_b.sv(26) @ 0: 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 component_a.sv(34) @ 0: 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) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

The next example shows the implementation of the can_put() method.
❮ Previous Next ❯

UVM TLM Tutorial

TLM Tutorial

❮ Previous Next ❯

UVM TLM Examples

TLM Examples

Blocking Port -> Imp Port
Port -> Imp Port Blocking Port Behaviour
NonBlocking Port -> Imp Port NonBlocking
Port -> Imp Port can_put method NonBlocking
Blocking Port -> Export -> Imp_port
Port -> Port -> Imp_port
Port -> Port -> Export -> Imp_port
Port -> Port -> Export -> Export -> Imp_port
Get Port -> imp_port
NonBlocking Get Port -> imp_port NonBlocking
Get Port -> imp_port can_get method NonBlocking
TLM FIFO TLM FIFO
TLM FIFO NonBlocking
TLM Analysis Port Analysis Imp Port and Analysis FIFO TLM Analysis Port Analysis Imp port
TLM Analysis Port with multi analysis imp port
TLM Analysis Port Multi Subscribers Analysis imp port
TLM Analysis Port Multi Subscribers with multi Analysis imp port
TLM Analysis FIFO

❮ Previous Next ❯

UVM TLM Analysis FIFO

TLM Analysis FIFO

TLM Analysis FIFO
TLM Analysis FIFO
  • An analysis_fifo is a uvm_tlm_fifo#(T) with an unbounded size and a write Method
  • It can be used any place a uvm_analysis_imp is used
  • Typical usage is as a buffer between a uvm_analysis_port in an initiator component and TLM1 target component

TLM Analysis FIFO Classes

uvm_tlm_analysis_fifo#(T) An analysis_fifo is a uvm_tlm_fifo#(T) with an unbounded size and a write method

Ports

analysis_export #(T)

The analysis_export provides the write method to all connected analysis ports and parent exports

function void write (T t)

Methods

new

This is a constructor method used for the creation of TLM Analysis FIFO

function new (string name,
              uvm_component parent = null);

❮ Previous Next ❯

UVM TLM FIFO

UVM TLM FIFO

The TLM FIFO provides storage for the transactions between two independently running processes. We have seen put and get methods operates with only one outstanding transaction at a time i.e it is allowed to send the transaction Only after consumption of the previously sent transaction, in this case, the sender and receiver must be in sync else lead to blocking in one of the components.

What if the case where the sender needs not wait for the receiver acknowledgment, it just wants to store it in memory and the receiver can consume whenever required. in this sender and The receiver needs not to be in sync. Yes With TLM FIFO it is possible.

TLM FIFO
TLM FIFO
  • In TLM FIFO, the sender pushes the transactions to FIFO and whenever it required reiver pops it out or fetches from the FIFO
  • Transactions are put into the FIFO via the put_export method
  • Transactions are fetched from the FIFO via the get_peek_export method
  • As its FIFO (First In First Out), transactions are fetched from the FIFO in the order they are put

TLM FIFO Classes

uvm_tlm_fifo #(T)

This class provides storage of transactions between two independently running processes

TLM FIFO Methods

new

This is a constructor method used for the creation of TLM FIFO

function new (string name,
              uvm_component parent,
              int size=1);

The name and parent are the normal uvm_component constructor arguments
The size indicates the maximum size of the FIFO; a value of zero indicates no upper bound

size

Calling size() returns the size of the FIFO
A return value of 0 indicates the FIFO capacity has no limit

used

Returns the number of entries put into the FIFO

is_empty

Returns 1 when there are no entries in the FIFO, 0 otherwise

is_full

Returns 1 when the number of entries in the FIFO is equal to its size, 0 otherwise

flush

Calling flush method will Remove all entries from the FIFO
after the flush method call used method returns 0 and the is_empty method returns 1

Summary of TLM FIFOs

TLM FIFO
TLM FIFO

Next Section: TLM Analysis FIFO

For TLM Examples refer to TLM Examples
❮ Previous Next ❯