uvm event methods examples

uvm_event method examples

Below is the list of methods implemented in uvm_event_base,

  • new; Creates a new event object
  • wait_trigger; Waits for an event to be triggered
  • wait_ptrigger; Waits for a persistent trigger of the event, avoids race conditions
  • wait_on; Waits for the event to be activated for the first time, returns immediately if the event is already triggered
  • wait_off; Returns if the event is off, else waits for the event turned off via reset event call
  • is_on; Returns 1 if the event has triggered
  • is_off; Returns 1 if the event has not been triggered
  • reset; resets the event to its off state
  • get_trigger_time; Returns the last time at which the event got triggered is_on is_off reset
  • get_num_waiters; Returns the number of processes waiting on the event

This section will see how to use these methods.

event examples

uvm_event and uvm_ptrigger show the usage of wait_trigger and wait_ptrigger respectively.

wait_on example

We know that event trigger and wait_trigger are a one-to-one mapping, i.e one event trigger will only unblock the one wait_trigger. one more wait_trigger will wait for the one more trigger.

But in the case of wait_on, the wait_on returns once the event is triggered until the event is off or reset.

module uvm_events_ex;
  uvm_event ev_1; //declaring uvm_event ev_1
  
  initial begin
    ev_1 = new(); //Creating an event
    
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time," Triggering The Event");
        ev_1.trigger;
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        ev_1.wait_on;
        $display($time," Event is on");
        #100;
        $display($time," Event is on");
      end
    join
  end
endmodule

Simulator Output

0 Waiting for the Event to trigger
40 Triggering The Event
40 Event is on
140 Event is on

Click to execute on   

wait_off and reset

module uvm_events_ex;
  uvm_event ev_1; //declaring uvm_event ev_1
  
  initial begin
    ev_1 = new(); //Creating an event
    
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time," Triggering The Event");
        ev_1.trigger;
        #500;
        $display($time," Resetting The Event");
        ev_1.reset();
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        ev_1.wait_on;
        $display($time," Event is on");
        #100;
        $display($time," Event is on");
        $display($time," Waiting for the Event to reset");
        ev_1.wait_off;
        $display($time," Event is off");
      end
    join
  end
endmodule

Simulator Output

0 Waiting for the Event to trigger
40 Triggering The Event
40 Event is on
140 Event is on
140 Waiting for the Event to reset
540 Resetting The Event
540 Event is off

Click to execute on   

is_on is_off get_number_waiters

module uvm_events_ex;
  uvm_event ev_1; //declaring uvm_event ev_1
  
  initial begin
    ev_1 = new(); //Creating an event
    
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time," Number of waiting trigger are %0d",ev_1.get_num_waiters());
        $display($time," Triggering The Event");
        ev_1.trigger;
        #500;
        $display($time," Resetting The Event");
        ev_1.reset();
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        ev_1.wait_on;
        if(ev_1.is_on) $display($time," Event is on");
        $display($time," Waiting for the Event to reset");
        ev_1.wait_off;
        if(ev_1.is_off) $display($time," Event is off");
      end
    join
  end
endmodule

Simulator Output

0 Waiting for the Event to trigger
40 Number of waiting trigger are 1
40 Triggering The Event
40 Event is on
40 Waiting for the Event to reset
540 Resetting The Event
540 Event is off

Click to execute on   

❮ Previous Next ❯

uvm event pool

uvm_event_pool

uvm_event_pool is a pool that stores the uvm_events.

uvm_event is used to synchronize the two processes. If the processes to trigger and wait for a trigger of an event are running in different components then it is required to share the event handle across the components. the uvm_event class makes it easy by providing uvm_event_pool.

Calling uvm_event_pool::get_global(“event_name”) method returns an event handle.

get_global Returns the specified item instance from the global item pool.

Refer to the uvm_pool for more details.

uvm event pool example

The below example consists of two components comp_a and comp_b. event triggering is in comp_a and wait for the event trigger in comp_b. it is required to share the same event handle across the components.

uvm_event_pool::get_global(“ev_ab”) is used to get the event handle. it will return the handle with the event name ev_ab.

Note:  In both component’s event is retrieved with the key “ev_ab”.

comp_a

class component_a extends uvm_component; 
  
  `uvm_component_utils(component_a)
  
  uvm_event ev; //Step-1. Declaring the event
  
  //--------------------------------------- 
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction : new

  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    //Step-2. Get the event handle from event pool
    ev = uvm_event_pool::get_global("ev_ab"); 
    
    `uvm_info(get_type_name(),$sformatf(" Before triggering the event"),UVM_LOW)
    #10;
    
    //Step-3. Triggering an event
    ev.trigger();
    
    `uvm_info(get_type_name(),$sformatf(" After triggering the event"),UVM_LOW)

    phase.drop_objection(this);
  endtask : run_phase

endclass : component_a

comp_b

class component_b extends uvm_component;

  `uvm_component_utils(component_b)
  
  uvm_event ev; //Step-1. Declaring the event
  
  //--------------------------------------- 
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction : new
  
  //---------------------------------------
  // run_phase 
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    //Step-2. Get the event handle from event pool
    ev = uvm_event_pool::get_global("ev_ab");
    
    `uvm_info(get_type_name(),$sformatf(" waiting for the event trigger"),UVM_LOW)
    
    //Step-3. waiting for event trigger
    ev.wait_trigger;
    
    `uvm_info(get_type_name(),$sformatf(" event got triggerd"),UVM_LOW)

    phase.drop_objection(this);
  endtask : run_phase

endclass : component_b

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1832
comp_a component_a - @1901
comp_b component_b - @1932
--------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.comp_b [component_b] waiting for the event trigger
UVM_INFO component_a.sv(26) @ 0: uvm_test_top.comp_a [component_a] Before triggering the event
UVM_INFO component_a.sv(31) @ 10: uvm_test_top.comp_a [component_a] After triggering the event
UVM_INFO component_b.sv(30) @ 10: uvm_test_top.comp_b [component_b] event got triggerd
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 10: reporter [TEST_DONE]
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 10: reporter [UVM/REPORT/SERVER]

Click to execute on   

retrieving event with different key

The below example is similar to the above example, but the event from the global_pool is retrieved with the different key. i.e, both components will not use the same event, which leads to triggering one event and waiting for another event trigger.

In comp_a event is retrieved with key ev_ab.

ev = uvm_event_pool::get_global("ev_ab");

In comp_b event is retrieved with key ev_ba.

ev = uvm_event_pool::get_global("ev_ba");

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top basic_test - @1832
comp_a component_a - @1901
comp_b component_b - @1932
--------------------------------------
UVM_INFO component_b.sv(26) @ 0: uvm_test_top.comp_b [component_b] waiting for the event trigger
UVM_INFO component_a.sv(26) @ 0: uvm_test_top.comp_a [component_a] Before triggering the event
UVM_INFO component_a.sv(31) @ 10: uvm_test_top.comp_a [component_a] After triggering the event
UVM_FATAL /playground_lib/uvm-1.2/src/base/uvm_phase.svh(1491) @ 9200000000000: reporter
[PH_TIMEOUT] Default timeout of 9200000000000 hit, indicating a probable testbench issue
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 9200000000000: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

uvm event

uvm_event

The uvm_event class is an extension of the uvm_event_base class. The uvm_event_base class is a wrapper class around the SystemVerilog event construct. uvm_event_base class is an abstract class.

Events are static objects useful for synchronization between the process. Event operations are of two staged processes in which one process will trigger the event, and the other processes will wait for an event to be triggered.

In order to ease the event usage, the uvm_event_base class has many methods implemented in it.

UVM Event Methods

  • new; Creates a new event object
  • wait_trigger; Waits for an event to be triggered
  • wait_ptrigger; Waits for a persistent trigger of the event, avoids race conditions
  • wait_on; Waits for the event to be activated for the first time, returns immediately if the event is already triggered
  • wait_off; Returns if the event is off, else waits for the event turned off via reset event call
  • is_on; Returns 1 if the event has triggered
  • is_off; Returns 1 if the event has not been triggered
  • reset; resets the event to its off state
  • get_trigger_time; Returns the last time at which the event got triggered is_on is_off reset
  • get_num_waiters; Returns the number of processes waiting on the event

UVM Event Syntax

uvm_event event_name;      // Event declaration

event_name = new();        // Creating an event

event_name.trigger();      // Triggering event

event_name.wait_trigger(); // Waiting for event trigger

UVM Event Examples

Wait for event trigger and then the event trigger

In the below example,
ev_1 is an uvm_event; There are two processes running in parallel, event triggering will happen in one of the processes and waiting for the event will happen in the other process.

The waiting for trigger will get unblocked after the event triggering and then the lines below it will get executed.

module uvm_events_ex;
  uvm_event ev_1; //Step-1. Declaring uvm_event ev_1
  
  initial begin
    ev_1 = new(); //Step-2. Creating an event
    
    fork
      //Process-1, triggers the event
      begin
        #40;
        $display($time," Triggering The Event");
        ev_1.trigger;  //Step-4. Trigger the event
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        ev_1.wait_trigger;  //Step-3. Waiting for event trigger
        $display($time," Event triggerd");  
      end
    join
  end
endmodule

Simulator Output

0 Waiting for the Event to trigger
40 Triggering The Event
40 Event triggered

Click to execute on   

event trigger and then Wait for event trigger

In the below example,
The event will be triggered before waiting for the event execution, the wait_trigger will keep waiting and leads to a deadlock, the statement after the wait_trigger will not get executed.

module uvm_events_ex;
  uvm_event ev_1; //declaring event ev_1
  
  initial begin
    ev_1 = new(); //Creating an event
    
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time," Triggering The Event");
        ev_1.trigger;
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        #60;
        ev_1.wait_trigger;
        $display($time," Event triggered");
      end
    join
  end
  initial begin
    #100;
    $display($time," Ending the Simulation");
    $finish;
  end
endmodule

Simulator Output

0 Waiting for the Event to trigger
40 Triggering The Event
100 Ending the Simulation

Click to execute on   

event trigger and wait for event trigger at the same time

In the below example,
The event triggering and wait_trigger will get executed simultaneously. Due to a race condition, wait_trigger will miss the trigger sampling which leads to a deadlock, the statement after the wait_trigger will not get executed.

module uvm_events_ex;
  uvm_event ev_1; //declaring uvm_event ev_1
  
  initial begin
    ev_1 = new(); //Creating an event
    
    fork
      //process-1, triggers the event
      begin
        $display($time," Triggering The Event");
        ev_1.trigger;
      end
      
      //process-2, wait for the event to trigger
      begin
        $display($time," Waiting for the Event to trigger");
        ev_1.wait_trigger;
        $display($time," Event triggered");
      end
    join
  end 
  
  initial begin
    #100;
    $display($time," Ending the Simulation");
    $finish;
  end
endmodule

Simulator Output

0 Triggering The Event
0 Waiting for the Event to trigger
100 Ending the Simulation

Click to execute on   

The Next example provides a solution to overcome from a race condition.
❮ Previous Next ❯

TLM Analysis FIFO example

TLM Analysis FIFO

UVM TLM Analysis FIFO
UVM TLM Analysis FIFO

TLM Analysis FIFO enables the implementing of FIFO in consumers and connects it directly to the analysis port. This example shows a connecting analysis port to an analysis FIFO.

TLM Analysis FIFO TesetBench Components are,

—————————————————————-
Name                     Type
—————————————————————-
uvm_test_top                    basic_test
env                                  environment
comp_a                         component_a
analysis_port           uvm_analysis_port
comp_b                         component_b
analy_fifo                uvm_tlm_analysis_fifo #(T)
analysis_export     uvm_analysis_imp
get_ap                    uvm_analysis_port
get_peek_export    uvm_get_peek_imp
put_ap                    uvm_analysis_port
put_export             uvm_put_imp
—————————————————————-

Implementing analysis port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis port
  uvm_analysis_port#(transaction) analysis_port;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    
    //Step-2. Creating analysis port
    analysis_port = new("analysis_port", this);
  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)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port write method"),UVM_LOW)
    //Ste-3. Calling write method
    analysis_port.write(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port write method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implementing analysis FIFO in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis FIFO
  uvm_tlm_analysis_fifo #(transaction) analy_fifo;  
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-2. Creating analysis FIFO
    analy_fifo = new("analy_fifo", this);
  endfunction : new
  
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    #100;
    `uvm_info(get_type_name(),$sformatf(" Before calling analysis fifo get method"),UVM_LOW)
    //Step.3 - Getting trans from FIFO
    analy_fifo.get(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling analysis fifo 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

Connecting analysis port and analysis FIFO in env

function void connect_phase(uvm_phase phase);
  //Connecting analysis port to analysis FIFO
  comp_a.analysis_port.connect(comp_b.analy_fifo.analysis_export);
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
----------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------
uvm_test_top basic_test - @1841
 env environment - @1910
 comp_a component_a - @1942
 analysis_port uvm_analysis_port - @1977
 comp_b component_b - @2010
 analy_fifo uvm_tlm_analysis_fifo #(T) - @2008
 analysis_export uvm_analysis_imp - @2217
 get_ap uvm_analysis_port - @2181
 get_peek_export uvm_get_peek_imp - @2111
 put_ap uvm_analysis_port - @2146
 put_export uvm_put_imp - @2076
----------------------------------------------------------------
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 - @2273
 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 write method
UVM_INFO component_a.sv(34) @ 0: uvm_test_top.env.comp_a [component_a] After calling port write method
UVM_INFO component_b.sv(27) @ 100: uvm_test_top.env.comp_b [component_b] Before calling analysis fifo get method
UVM_INFO component_b.sv(29) @ 100: uvm_test_top.env.comp_b [component_b] After calling analysis fifo get method
UVM_INFO component_b.sv(30) @ 100: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2273
 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) @ 100: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 100: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

TLM Analysis port multi Analysis imp port multi component

Multi Subscribers with Multiports

Analysis Port Multi Imp port
Analysis Port Multi Imp port

This example shows connecting the same analysis port to analysis imp ports of multiple components.

TLM Analysis TesetBench Components are,

——————————————————————-
Name                              Type
——————————————————————-
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
analysis_port        uvm_analysis_port
comp_b                     component_b
analysis_imp_a     uvm_analysis_imp_port_ba
analysis_imp_b     uvm_analysis_imp_port_bb
comp_c                     component_c
analysis_imp_a     uvm_analysis_imp_port_ca
analysis_imp_b     uvm_analysis_imp_port_cb
——————————————————————-

Implementing analysis port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis port
  uvm_analysis_port#(transaction) analysis_port;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    
    //Step-2. Creating analysis port
    analysis_port = new("analysis_port", this);
  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)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port write method"),UVM_LOW)
    //Ste-3. Calling write method
    analysis_port.write(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port write method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implementing analysis imp_port’s in comp_b

//Step-1. Define analysis imp ports
`uvm_analysis_imp_decl(_port_ba)
`uvm_analysis_imp_decl(_port_bb)
class component_b extends uvm_component;
  
  transaction trans;
  //Step-2. Declare the analysis imp ports
  uvm_analysis_imp_port_ba #(transaction,component_b) analysis_imp_a; 
  uvm_analysis_imp_port_bb #(transaction,component_b) analysis_imp_b;
  
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-3. Create the analysis imp ports
    analysis_imp_a = new("analysis_imp_a", this);
    analysis_imp_b = new("analysis_imp_b", this);
  endfunction : new
  
  //Step-4. Implement the write method write_port_ba
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_ba(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_ba method.
                               Received trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
  
  //Step-4. Implement the write method write_port_bb
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_bb(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_bb method.
                               Received trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
  
endclass : component_b

Implementing analysis imp_port’s in comp_c

//Step-1. Define analysis imp ports
`uvm_analysis_imp_decl(_port_ca)
`uvm_analysis_imp_decl(_port_cb)
class component_c extends uvm_component;
  
  transaction trans;
  //Step-2. Declare the analysis imp ports
  uvm_analysis_imp_port_ca #(transaction,component_c) analysis_imp_a; 
  uvm_analysis_imp_port_cb #(transaction,component_c) analysis_imp_b;
  
  `uvm_component_utils(component_c)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-3. Create the analysis imp ports
    analysis_imp_a = new("analysis_imp_a", this);
    analysis_imp_b = new("analysis_imp_b", this);
  endfunction : new
  
  //Step-4. Implement the write method write_port_ca
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_ca(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_ba method.
                               Received trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
  
  //Step-4. Implement the write method write_port_cb
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_cb(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_bb method.
                               Received trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
endclass : component_c

Connecting analysis port and analysis imp_ports in env

function void connect_phase(uvm_phase phase);
  //Connecting analysis port to imp port
  comp_a.analysis_port.connect(comp_b.analysis_imp_a);
  comp_a.analysis_port.connect(comp_b.analysis_imp_b);
  comp_a.analysis_port.connect(comp_c.analysis_imp_a);
  comp_a.analysis_port.connect(comp_c.analysis_imp_b);
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
-----------------------------------------------------------
Name Type Size Value
-----------------------------------------------------------
uvm_test_top basic_test - @1842
 env environment - @1911
 comp_a component_a - @1943
 analysis_port uvm_analysis_port - @1978
 comp_b component_b - @2011
 analysis_imp_a uvm_analysis_imp_port_ba - @2046
 analysis_imp_b uvm_analysis_imp_port_bb - @2081
 comp_c component_c - @2112
 analysis_imp_a uvm_analysis_imp_port_ca - @2147
 analysis_imp_b uvm_analysis_imp_port_cb - @2182
-----------------------------------------------------------
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 - @2235
 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 write method
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] Inside write_port_ba method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2235
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_b.sv(37) @ 0: uvm_test_top.env.comp_b [component_b] Inside write_port_bb method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(38) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2235
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_c.sv(29) @ 0: uvm_test_top.env.comp_c [component_c] Inside write_port_ca method. Recived trans On Analysis Imp Port
UVM_INFO component_c.sv(30) @ 0: uvm_test_top.env.comp_c [component_c] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2235
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_c.sv(37) @ 0: uvm_test_top.env.comp_c [component_c] Inside write_port_cb method. Recived trans On Analysis Imp Port
UVM_INFO component_c.sv(38) @ 0: uvm_test_top.env.comp_c [component_c] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2235
 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 write 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   

❮ Previous Next ❯

TLM Analysis port single Analysis imp port multi component

Multi Subscribers with a single port

Multiple Analysis Imp port
Multiple Analysis Imp port

This example shows connecting the same analysis port to analysis imp port of multiple components.

TLM Analysis TesetBench Components are,

————————————————————–
Name                              Type
————————————————————–
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
analysis_port        uvm_analysis_port
comp_b                     component_b
analysis_imp         uvm_analysis_imp
comp_c                     component_c
analysis_imp         uvm_analysis_imp
————————————————————–

Implementing analysis port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis port
  uvm_analysis_port#(transaction) analysis_port;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    
    //Step-2. Creating analysis port
    analysis_port = new("analysis_port", this);
  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)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port write method"),UVM_LOW)
    //Ste-3. Calling write method
    analysis_port.write(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port write method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implementing analysis imp_port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis imp port
  uvm_analysis_imp#(transaction,component_b) analysis_imp; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-2. Creating analysis imp_port
    analysis_imp = new("analysis_imp", this);
  endfunction : new
  
  //---------------------------------------
  // Analysis Imp port write method
  //---------------------------------------
  //Step-3. Implementing write method
  virtual function void write(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write method. Recived
                                          trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
endclass : component_b

Implementing analysis imp_port in comp_c

class component_c extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis imp port
  uvm_analysis_imp#(transaction,component_c) analysis_imp; 
  `uvm_component_utils(component_c)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-2. Creating analysis imp_port
    analysis_imp = new("analysis_imp", this);
  endfunction : new
  
  //---------------------------------------
  // Analysis Imp port write method
  //---------------------------------------
  //Step-3. Implementing write method
  virtual function void write(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write method. Recived
                                          trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
endclass : component_c

Connecting analysis port and analysis imp_ports in env

function void connect_phase(uvm_phase phase);
  //Connecting analysis port to imp port
  comp_a.analysis_port.connect(comp_b.analysis_imp);
  comp_a.analysis_port.connect(comp_c.analysis_imp);
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
---------------------------------------------------
Name Type Size Value
---------------------------------------------------
uvm_test_top basic_test - @1842
 env environment - @1911
 comp_a component_a - @1943
 analysis_port uvm_analysis_port - @1978
 comp_b component_b - @2011
 analysis_imp uvm_analysis_imp - @2046
 comp_c component_c - @2077
 analysis_imp uvm_analysis_imp - @2112
---------------------------------------------------
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 - @2151
 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 write method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside write method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2151
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_c.sv(24) @ 0: uvm_test_top.env.comp_c [component_c] Inside write method. Recived trans On Analysis Imp Port
UVM_INFO component_c.sv(25) @ 0: uvm_test_top.env.comp_c [component_c] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2151
 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 write 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   

❮ Previous Next ❯

TLM Analysis port multi Analysis imp port

Connecting multiple ports to a single analysis port

Analysis Port Multi Imp port
Analysis Port Multi Imp port

This example shows connecting analysis port to multiple analysis imp ports.

TLM Analysis ports TesetBench Components are,

——————————————————————-
Name                              Type
——————————————————————-
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
analysis_port        uvm_analysis_port
comp_b                     component_b
analysis_imp_a     uvm_analysis_imp_port_a
analysis_imp_b     uvm_analysis_imp_port_b
——————————————————————-

Implementing analysis port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis port
  uvm_analysis_port#(transaction) analysis_port;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    
    //Step-2. Creating analysis port
    analysis_port = new("analysis_port", this);
  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)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port write method"),UVM_LOW)
    //Ste-3. Calling write method
    analysis_port.write(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port write method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implementing analysis imp_ports in comp_b

Implementing analysis imp_ports in a component involves below steps,

1. define the analysis_imp_ports using macro

`uvm_analysis_imp_decl(port_identifier)
//port_identifier is the user defined name to differentiate the imp ports

defining ports with the name _port_a and _port_b

`uvm_analysis_imp_decl(_port_a)
`uvm_analysis_imp_decl(_port_b)

2. Declare the analysis ports

uvm_analysis_imp<> #(t,T) port_name;

declaring two ports using the above syntax,

uvm_analysis_imp_port_a #(transaction,component_b) analysis_imp_a; 
uvm_analysis_imp_port_b #(transaction,component_b) analysis_imp_b;

3. Implement the write methods for each port,

function void write_port_identifier;

Implementing write methods with the above syntax,

Method for analysis_imp_a

virtual function void write_port_a(transaction trans);
  `uvm_info(get_type_name(),$sformatf(" Inside write_port_a method.
                                        Received trans On Analysis Imp Port"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)
endfunction

Method for analysis_imp_b

virtual function void write_port_b(transaction trans);
  `uvm_info(get_type_name(),$sformatf(" Inside write_port_b method.
                                        Received trans On Analysis Imp Port"),UVM_LOW)
  `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)
endfunction

Complete comp_b code,

`uvm_analysis_imp_decl(_port_a)
`uvm_analysis_imp_decl(_port_b)
class component_b extends uvm_component;
  
  transaction trans;
  uvm_analysis_imp_port_a #(transaction,component_b) analysis_imp_a; 
  uvm_analysis_imp_port_b #(transaction,component_b) analysis_imp_b;
  
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    analysis_imp_a = new("analysis_imp_a", this);
    analysis_imp_b = new("analysis_imp_b", this);
  endfunction : new
  
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_a(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_a method.
                                          Recived trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
  
  //---------------------------------------
  // Analysis port write method
  //---------------------------------------
  virtual function void write_port_b(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write_port_b method.
                                          Recived trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
  
endclass : component_b

Connecting Analysis port with the imp_ports in env

function void connect_phase(uvm_phase phase);
  //Connecting analysis_port to imp_ports
  comp_a.analysis_port.connect(comp_b.analysis_imp_a);
  comp_a.analysis_port.connect(comp_b.analysis_imp_b);
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
 analysis_port uvm_analysis_port - @1975
 comp_b component_b - @2008
 analysis_imp_a uvm_analysis_imp_port_a - @2043
 analysis_imp_b uvm_analysis_imp_port_b - @2078
----------------------------------------------------------
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 - @209 
 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 write method
UVM_INFO component_b.sv(29) @ 0: uvm_test_top.env.comp_b [component_b] Inside write_port_a method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(30) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @209 
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_b.sv(37) @ 0: uvm_test_top.env.comp_b [component_b] Inside write_port_b method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(38) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @209 
 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 write 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   

❮ Previous Next ❯

TLM Analysis port Analysis imp port

Connecting Analysis port and Analysis imp port

Analysis Port Imp port
Analysis Port Imp port

TLM Analysis port and analysis imp port enable broadcasting a transaction to one or many components. This example shows connecting analysis port to an analysis imp port.

TLM Analysis port TesetBench Components are,

————————————————————–
Name                              Type
————————————————————–
uvm_test_top                  basic_test
env                                environment
comp_a                     component_a
analysis_port        uvm_analysis_port
comp_b                     component_b
analysis_imp         uvm_analysis_imp
————————————————————–

Implementing analysis port in comp_a

class component_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis port
  uvm_analysis_port#(transaction) analysis_port;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    
    //Step-2. Creating analysis port
    analysis_port = new("analysis_port", this);
  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)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port write method"),UVM_LOW)
    //Ste-3. Calling write method
    analysis_port.write(trans);
    `uvm_info(get_type_name(),$sformatf(" After  calling port write method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implementing analysis imp_port in comp_b

class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring analysis imp port
  uvm_analysis_imp#(transaction,component_b) analysis_imp; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    //Step-2. Creating analysis imp_port
    analysis_imp = new("analysis_imp", this);
  endfunction : new
  
  //---------------------------------------
  // Analysis Imp port write method
  //---------------------------------------
  //Step-3. Implementing write method
  virtual function void write(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Inside write method. Recived
                                          trans On Analysis Imp Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",
                                          trans.sprint()),UVM_LOW)
  endfunction
endclass : component_b

Connecting analysis port and analysis imp_port in env

function void connect_phase(uvm_phase phase);
  //Connecting analysis port to imp port
  comp_a.analysis_port.connect(comp_b.analysis_imp);
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
 analysis_port uvm_analysis_port - @1975
 comp_b component_b - @2008
 analysis_imp uvm_analysis_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 write method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Inside write method. Recived trans On Analysis Imp Port
UVM_INFO component_b.sv(25) @ 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 write 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   

❮ Previous Next ❯

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 ❯