Events in a uvm_sequence_item for slave agent synchronization

Hello,

I have implemented a slave agent for a memory mapped interface in UVM. For read actions, some method is needed to make sure that the slave can respond with data based on an address that is part of the same transaction (and thus are both variables in a uvm_sequence_item).

I came up with a solution using two events in the sequence item. It works well and it seems a nice solution, but I could not find something like this on the internet, so I would like to get the opinion of more experienced UVM users on this solution.

Note that the agent is actually a pipelined agent, because the protocol is pipelined.

Consider the following sequence item, this example item only describes a read action.

class bus_item extends uvm_sequence_item;
	bit[31:0] addr;
	bit [31:0] rd_data;
	
	event address_phase_done;
	event data_phase_start;
endclass

This is the run_phase of the driver:

task run_phase(uvm_phase phase);
	seq_item_port.get(item);
	
	drive_address_phase(item);
	
	->item.address_phase_done;
	@item.data_phase_start;
	
	drive_data_phase(item);
	
	seq_item_port.put(item);	
endtask

This is the body task in a sequence that controls the slave:

task body();
	start_item(item);
	finish_item(item);
	
	@item.address_phase_done;
	item.data = item.addr; // echo address as data
	->item.data_phase_start;

	get_response(item);
endtask

What do you think of something like this? Is it an acceptable solution? Are there better ways to do this?

Thanks!