The transfer of request and response sequence items between sequences and their target driver is facilitated by a TLM communication mechanism implemented in the sequencer.
Sending a sequence_item to a driver:
Step 1 - Creation
The sequence_item is derived from uvm_object and should be created via the factory:
Using the factory creation method allows the sequence_item to be overridden with a sequence_item of a derived type if required.
Step 2 - Ready - start_item()
The start_item() call is made, passing the sequence_item handle as an argument. This call blocks until the sequencer grants the sequence and the sequence_item access to the driver.
Step 3 - Set
The sequence_item is prepared for use, usually through randomization, but it may also be initialised by setting properties directly.
Step 4 - Go - finish_item()
The finish_item() call is made, which blocks until the driver has completed its side of the transfer protocol for the item. No simulation time should be consumed between start_item() and finish_item().
Step 5 - Response - get_response()
This step is optional, and is only used if the driver sends a response to indicate to indicate that it has completed transaction associated with the sequence_item. The get_response() call blocks until a response item is available from the sequencers response FIFO.
The alternative approach is to generate the sequence_item before the start_item() call, in this case the item is generated before it is necessarily clearhow it is going to be used.
Driver side Operation:
This method blocks until a REQ sequence_item is available in the sequencers request FIFO and then returns with a pointer to the REQ object.
The get_next_item() call implements half of the driver-sequencer protocol handshake, and it must be followed by an item_done() call which completes the handshake. Making another get_next_item() call before issuing an item_done() call will result in a protocol error and driver-sequencer deadlock.
This is a non-blocking variant of the get_next_item() method. It will return a null pointer if there is no REQ sequence_item available in the sequencers request FIFO. However, if there is a REQ sequence_item available it will complete the first half of the driver-sequencer handshake and must be followed by an item_done() call to complete the handshake.
The non-blocking item_done() method completes the driver-sequencer handshake and it should be called after a get_next_item() or a successful try_next_item() call.
The get_next_item() method initiate the sequencer arbitration process, which results in a sequence_item being returned from the active sequence which has selected. This means that the driver is effectively pulling sequence_items from the active sequences as it needs them.
When the handle to a sequence_item is passed as an argument to
the finish_item() method the drivers get_next_item() method call completes with a pointer to the same sequence_item. When the driver makes any changes to the sequence_item it is really updating the object inside the sequence. The drivers call to item_done() unblocks the finish_item() call in the sequence and then the sequence can access the fields in the
sequence_item, including those which the driver may have updated as part of the response side of the pin level transaction.
uvm_sequence and uvm_driver have predefined sequence_item for both request and response.
So, you can directly use predefined variables for sequence_item,