My sequence is calling the `uvm_send macro and it never returns from that macro. I added a uvm_info message in that macro (in uvm_sequence_defines.svh) just before calling finish_item, and I also added some uvm_info messages in the finish_item (defined in uvm_sequence_base.svh). I see that the message before calling finish_item is displayed. However, the first uvm_info message from finish_item is not being displayed. I don’t know where that finish_item call is going, but it’s definitely not going to the task defined in uvm_sequence_base.svh in my case. Is there something I’m missing here?
It’s difficult to answer your question without seeing what modifications you’ve made to the UVM code.
In order for finish_item() to return you will need the target driver to call seq_item_port.get() or seq_item_port.item_done(), is this happening?
In reply to mperyer:
I agree it’s difficult to debug without looking at the code. I actually found that I have problems mainly when I start a virtual sequence. test, vseq, seq code below. My environment has 2 instances of the same agent. I observed the following three things.
- When I uncomment the vseq.start below (running a vseq), simulation gets stuck at the finish_item as I mentioned in the initial post.
- When I uncomment seq1 alone, test runs as I expected (seq1 runs on agent0’s sequencer)
- When I uncomment seq1 and seq2, I see that only seq1 runs on agent0’s sequencer (and seq2 doesn’t run on agent1’s sequencer)
Test:
task main_phase(uvm_phase phase);
seq seq1,seq2;
vseq vseq;
vseq = new(“vseq”);
seq1 = new(“seq1”);
seq2 = new(“seq2”);
//vseq.start(env.virtual_sequencer, null);
fork
begin
//seq1.start(env.agent0.sequencer, null);
//seq2.start(env.agent1.sequencer, null);
end
join
endtask : main_phase
class vseq extends uvm_sequence #(trans)
function new (string name = “vseq”);
super.new(name);
endfunction : new
seq seq1,seq2;
`uvm_sequence_utils(vseq, virtual_sequencer)
virtual task body();
fork
uvm_do_on(seq1, p_sequencer.agent0_sequencer)
uvm_do_on(seq2, p_sequencer.agent1_sequencer)
join
endtask : body
endclass : vseq
class seq extends uvm_sequence #(trans)
//constructor
task body;
trans trans;
for (int i=0; i < 10; i++) begin
`uvm_do(trans)
end
endtask : body
endclass
What happens if you try running just seq2 on agent1, without running via a virtual sequencer?
seq2.start(env.agent1.sequencer, null);
If this doesn’t work, then you will have to trace through why that is. I suspect that you may have mis-connected something in the env, especially if the same seq works for the same type of agent.
BTW - You may also like to consider removing all the uvm_sequence_utils()/
uvm_sequencer_utils() macro code, since it is deprecated. Replace with uvm_object_utils and
uvm_component_utils() respectively.
In reply to mperyer:
mperyer,
Sorry, I was pulled into other things, and didn’t get to work on the cool stuff (UVM :)).
I wasn’t able to run any sequence on agent1 (when I tried your experiment). After banging my head against the wall several times while I was checking the connectivity, I found out that my agent1’s interface clock isn’t being driven in my testbench. Thank you so much for all your help.
Thanks for pointing out the uvm_sequence_utils thing. I was seeing warnings about the uvm_sequence_utils, but got confused because the 1.1 userguide had those macros at some places. Also, how do we access the p_sequencer variable if use object/component_utils macros?
There are two sequencer handles available in a sequence:
Unless you have created a sequencer which is a real extension of the uvm_sequencer, i.e. it contains extended properties and methods, then the m_sequencer handle will work. See:
http://verificationacademy.com/uvm-ovm/Sequences/API
You also don’t have to use a virtual sequencer - see: