In reply to kerulmodi:
Hi Kerulmodi,
I think i have found the problem and a workaround to avoid commenting the stop_sequences function.
As already described above, stop_sequences will kill the sending sequence. However, as you noticed, it is not true that it will kill the sequence that is currently active in the sequencer. The stop_sequence function has a sequence registration mechanism. It will register the sequence used for a sequencer once the “uvm_send” has been sent from the sequence. No matter if the “uvm_send” and the transaction has already been processed and the sequencer is not doing anything, if the sequence did “uvm_send” over a sequencer, this sequence will be registered.
I understand, as you did, that this is not 100% OK but UVM do so. In my opinion, UVM should un-register that sequence once the driver of the sequencer has all objections dropped or is waiting for an item of the sequence. In other words, it should not kill an idle sequence.
OK. Now to the solutions.
I guess that you want to use stop_sequence to kill all unfinished sequence items from the sequence when a reset is monitored. This is the best reset handling approach i have seen in UVM, see this https://www.embedded.com/print/4396934 for more information of this approach. Therefore, i assume that you want to keep your stop_sequence() function in your code.
The workaround is simple, you just avoid using any UVM_DO or any “uvm_send” inside your virtual sequence. I explain. If you want to send your stimuli, then you need to create a sub-sequence (inside your virtual sequence) that wrap all the stimuli (“uvm_send” to any sequencer that uses stop_sequence). Doing that the registered and killed sequence (by stop_sequences) will be the sub-sequence and not your virtual sequence. (For completation, if you use the UVM register model functions (read/write/mirror/update) each time you write to a register of the UVM, the register model creates a subsequence for you so you don’t have to worry about wrapping those read/write/mirror/update register logic functions, they do already right)
For your code, the following need to be done (approximately):
Go from your current Virtual sequence:
class my_vir_seq extends uvm_sequence;
`uvm_object_utils(my_vir_seq)
`uvm_declare_p_sequencer(my_vir_seq)
process p_seq;
function new (string name = "my_vir_seq" );
super.new(name);
endfunction : new
task body();
my_tr tr;
p_seq = process :: self();
`uvm_info(get_name(),"sequence is running",UVM_LOW)
`uvm_do_on( tr, p_sequencer.my_seqr_h); // send transaction on leaf level sequencer
#1000; // Added delay to execute this sequence longer time
`uvm_info(get_name(),"sequence is completed",UVM_LOW)
endtask : body
endclass : my_vir_seq
To the new Virtual sequence:
typedef class my_sub_vir_seq;//forward declaration to be able to use this type inside my_vir_seq
class my_vir_seq extends uvm_sequence;
`uvm_object_utils(my_vir_seq)
`uvm_declare_p_sequencer(my_vir_seq)
process p_seq;
function new (string name = "my_vir_seq" );
super.new(name);
endfunction : new
task body();
p_seq = process :: self();
my_sub_vir_seq this_seq_has_all_stimuli_ready2bekilled;
this_seq_has_all_stimuli_ready2bekilled = my_sub_vir_seq::type_id::create("this_seq_has_all_stimuli_ready2bekilled");
this_seq_has_all_stimuli_ready2bekilled.start(p_sequencer.my_seqr_h);//the subsequence is started
endtask : body
endclass : my_vir_seq
//sub sequence with stimuli definition that is used inside the virtual sequence
class my_sub_vir_seq extends uvm_sequence;
`uvm_object_utils(my_sub_vir_seq )
`uvm_declare_p_sequencer(my_vir_seq)
process p_seq;
function new (string name = "my_sub_vir_seq " );
super.new(name);
endfunction : new
task body();
my_tr tr;
`uvm_info(get_name(),"sequence is running",UVM_LOW)
`uvm_do_on( tr, p_sequencer.my_seqr_h); // send transaction on leaf level sequencer
#1000; // Added delay to execute this sequence longer time
`uvm_info(get_name(),"sequence is completed",UVM_LOW)
endtask : body
endclass : my_sub_vir_seq
Of course, you can have in your virtual sequence the reset handling. In other words, you can for example detect a reset in your virtual sequence and restart your sub-sequence (the one with the stimuli) after reset or other stimuli.
I hope that this helps.
Best regards,
Jonathan