There are primarily two ways to start a sequence : use a
`uvm_do macro, or use the
start() method. If you have read How to execute sequences via `uvm_do macros ?, you might already know that
`uvm_do macros eventually call the
start() method, and the macros act as a wrapper to execute both data items and sequences on the default sequencer "m_sequencer".
uvm_sequence_item objects have a uvm_sequencer_base handle called m_sequencer, to which a different sequencer can be assigned. This can be achieved in the following ways:
virtual task start ( uvm_sequencer_base sequencer, uvm_sequence_base parent_sequence = null, int this_priority = -1, bit call_pre_post = 1 ); virtual function void set_sequencer (uvm_sequencer_base sequencer);
A sequence is always executed by the default sequencer. It's just that the default sequencer is made to point to the sequencer on which we want the sequence to execute on.
I have read your blog on sequencer and it is very helpful for me. but i have an doubt that can be not use TLM get/put like methods instead of seq_item_port.get_next_item/seq_item_port.item_done to communicate between sequencer and driver ?
What makes uvm_driver different from a uvm_component is that it contains a port called seq_item_port of type uvm_seq_item_pull_port. This port is specially developed for use in sequencer-driver communication, and a call to get_next_item() will result in the sequencer to provide a new item to the driver. Also, there are cases where the driver can send a response back to the sequencer, and the RSP serves well for the purpose.
we can use TLM get/put methods instead of seq_item_port.get_next_item/seq_item_port.item_done() methods. for example, we are having one driver (initiator) and one sequencer (target) and have to complete handshake process between them, then we will have to declare uvm_blocking_get_port() in driver and uvm_blocking_get_imp() in sequencer with get task. In driver's run_phase, call that get task for generating transactions which has defined in sequencer. In agent's connect_phase, connect both ports which are declared in driver and sequencer using connect method. since TLM get/put methods are blocking methods and has capability to complete the driver-sequencer handshake process by itself. get_next_item() is also a blocking method but it needs item_done() which is a non-blocking method to complete the handshake process and by using this method no need to declare any other ports in driver and sequencer, we can simply connect both components in agent's connect phase.