uvm_transaction

class uvm.base.uvm_transaction.UVMTransaction(name='', initiator=None)[source]

Bases: UVMObject

The UVMTransaction class is the root base class for UVM transactions. Inheriting all the methods of UVMObject, UVMTransaction adds a timing and recording interface.

This class provides timestamp properties, notification events, and transaction recording support.

Use of this class as a base for user-defined transactions is deprecated. Its subtype, uvm_sequence_item, shall be used as the base class for all user-defined transaction types.

The intended use of this API is via a uvm_driver to call accept_tr, begin_tr, and end_tr during the course of sequence item execution. These methods in the component base class will call into the corresponding methods in this class to set the corresponding timestamps (accept_time, begin_time, and end_time), trigger the corresponding event (begin_event and end_event, and, if enabled, record the transaction contents to a vendor-specific transaction database.

Note that get_next_item/item_done when called on a uvm_seq_item_pull_port will automatically trigger the begin_event and end_event via calls to begin_tr and end_tr. While convenient, it is generally the responsibility of drivers to mark a transaction’s progress during execution. To allow the driver or layering sequence to control sequence item timestamps, events, and recording, you must call UVM_SEQ_ITEM_PULL_IMP.disable_auto_item_recording at the beginning of the driver’s run_phase task.

Users may also use the transaction’s event pool, events, to define custom events for the driver to trigger and the sequences to wait on. Any in-between events such as marking the beginning of the address and data phases of transaction execution could be implemented via the events pool.

In pipelined protocols, the driver may release a sequence (return from finish_item or it’s uvm_do macro) before the item has been completed. If the driver uses the begin_tr/end_tr API in UVMComponent, the sequence can wait on the item’s end_event to block until the item was fully executed, as in the following example.

task uvm_execute(item, ...)
    // can use the `uvm_do macros as well
    start_item(item)
    item.randomize()
    finish_item(item)
    item.self.end_event.wait_on()
    // get_response(rsp, item.get_transaction_id()); //if needed
endtask

A simple two-stage pipeline driver that can execute address and data phases concurrently might be implemented as follows:

task run()

    // this driver supports a two-deep pipeline
    fork
      do_item()
      do_item()
    join
endtask


task do_item()

  forever begin
    mbus_item req

    lock.get()

    seq_item_port.get(req); // Completes the sequencer-driver handshake

    accept_tr(req)

      // request bus, wait for grant, etc.

    begin_tr(req)

      // execute address phase

    // allows next transaction to begin address phase
    lock.put()

      // execute data phase
      // (may trigger custom "data_phase" event here)

    end_tr(req)

  end

endtask: do_item
accept_tr(accept_time=0)[source]
do_accept_tr()[source]
begin_tr(begin_time=0)[source]
begin_child_tr(begin_time=0, parent_handle=0)[source]
do_begin_tr()[source]
end_tr(end_time=0, free_handle=1)[source]
do_end_tr()[source]
get_tr_handle()[source]
disable_recording()[source]
enable_recording(stream)[source]
is_recording_enabled()[source]
is_active()[source]
get_event_pool()[source]
set_initiator(initiator)[source]
get_accept_time()[source]
get_begin_time()[source]
get_end_time()[source]
set_transaction_id(id)[source]
get_transaction_id()[source]
m_begin_tr(begin_time=0, parent_handle=0)[source]