I am a bit confused on how to correctly kill a sequence. Here is what the UVM Cookbook ( from Mentor) say s about killing sequences.
Stopping a Sequence
Once started, sequences should not be stopped.
There are two methods available in the sequence and sequencer API that allow sequences to be killed. However,
neither method checks that the driver is not currently processing any sequence_items and the result is that any
item_done() or put() method called from the driver will either never reach the controlling sequence or will cause an
UVM fatal error to occur because the sequences return pointer queue has been flushed.
The methods are:
• .kill()
• .stop_sequences()
Do not use these methods unless you have some way of ensuring that the driver is inactive before making the call.
Now, based on past experiences, this is what I have done for killing sequences. This code is used for things like phase jumping when sequences need to be killed ban in the middle of the main_phase. Basically, we are stopping the sequences and then sending an event to the driver to stop it.
class agent_c extends uvm_agent;
`uvm_component_utils(agent_c)
sqr_c sqr;
drv_c drv;
...
virtual task pre_reset_phase(uvm_phase phase);
if(sqr && drv) begin
sqr.stop_sequences();
->drv.reset_driver;
end
endtask : pre_reset_phase
endclass : agent_c
Here is the corresponding code from the driver that kills the driver ( and presumably the item_done inside)
class drv_c extends uvm_driver;
`uvm_component_utils(drv_c)
event reset_driver;
...
virtual task run_phase(uvm_phase phase);
forever begin
@(posedge my_vi.rst_n);
fork
driver();
join_none
@(reset_driver);
disable fork;
cleanup();
end
endtask : run_phase
virtual task driver();
forever begin
...
end
endtask : driver
endclass : drv_c
The stop_sequences call does the following : (From the comments section for this function from uvm_sequencer.h)
// Tells the sequencer to kill all sequences and child sequences currently
// operating on the sequencer, and remove all requests, locks and responses
// that are currently queued. This essentially resets the sequencer to an
// idle state.
The question I have is if you have reset the sequencer to an idle state before you stop the driver, how does one ensure that the driver will not call an item_done on a transaction after the stop_sequences call and before the reset_driver call ? I have used the above code before and it has worked. What I am wondering is how this works ?
If the above is not the right way to kill sequences, what is the recommended way ?