Hi all , i am a beginner in UVM
I would like to know whether if the sequence must have to raise and drop phase ?
Without raising and dropping phase, will it be wrong?
i am confused with raising and dropping phase
Thanks a lot!!
In reply to peter:
You do not raise and drop a phase. You are raising and dropping objections.
This is required by the UVM. If you do not implement objections your simulation will stuck at time 0.
ojections can be implemented in any UVM component or in a sequence.
The recommendation is to implement as less as possible. The best and recommended way is to implement objections in the test.
In reply to peter:
Objections are not phases, they are flags that keep an existing phase active.
The general rule is your test should raise an objection, start the top-level sequence, then drop the objections. If all the blocking child sequences are hierarchical under the top-level sequences, you don’t need another objections.
If you have a sequence in an independent process (via fork/join_none), that sequence may need to raise an objections. What you want to avoid is a situation where you continually raise and drop objections over and over again as that may slow your test down, as well as make it more difficult to debug.
In reply to chr_sue:
If you do not implement objections your simulation will stuck at time 0.
Actually, with no objections, your simulation will end prematurely at time 0.
Hi ALL.
i find that raising objection and dropping objection usually putted in class sequence by DV engineer.But, i see another case which raising objection and dropping objection is putted in class uvm_test.
Here is the code. My question is which class i should raise objection and drop objection in ? class sequence or test?
Thanks!!
class crc7_test extends uvm_test;
`uvm_component_utils(crc7_test)
crc7_env c7_env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction:new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c7_env = crc7_env::type_id::create(.name("c7_env"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
crc7_sequence c7_seq;
phase.raise_objection(.obj(this));
c7_seq = crc7_sequence::type_id::create(.name("c7_seq"), .contxt(get_full_name()));
assert(c7_seq.randomize());
c7_seq.start(c7_env.c7_agent.c7_seqr);
phase.drop_objection(.obj(this));
endtask: run_phase
endclass: crc7_test
In reply to peter:
Normally, we should raise/drop objection in test class. That’s more popular way. Your example looks fine. If you are using “default sequence”, you have to implement objection in sequence class.
In reply to chris_le:
Chris, I do not agree with you. Using objections in a sequence does not depend how you are starting the sequence. But it is really unusual to have objections in a sequence.
What I see in some projects is people are implementing objections in all places where it is legal. This ends up in a big confusion when the simulation does not stop as expected. The debug effort to find the problem is huge. The better way is to start with 1 objection mechanism in the test. If you find this does not consider all your simulation aspects you can look for an additional place.
In reply to chr_sue:
Hi chr_sue,
I agreed that we should implement objection in the test. But I wanted to show him a case that we need to implement objection in the sequence (we can’t not implement in the test), that’s “default sequence”:
uvm_config_db #(uvm_object_wrapper)::set(this, "env.vseqr.main_phase", "default_sequence", my_vseq_c::get_type());
Of course, override the “default sequence” is not recommended but I’ve seen many projects use this mechanism.
Correct me if I’m wrong here.
Thanks
In reply to dave_59:
Hi all
Can anyone tell me why raise/drop objection should be located in test class?
can i put it to other cloass?
what is the procedure behind that?
I am so confused
Thanks a lot!!
In reply to peter:
For more details look here:
https://verificationacademy.com/cookbook/objections
In reply to dave_59:
In reply to chr_sue:
Actually, with no objections, your simulation will end prematurely at time 0.
Hi all, why the simulation without objections terminate at time 0 ?
In the pseudo code, i already delay 100ns , but why it terminate a time 0? Thank a lot!
here is pseudo code:
class xx extends uvm_test
function new xx
endfucntion
virtual task run_phase(uvm_phase phase);
#100ns;
`uvm_info("test","hihi",UVM_MEDIUM);
endtask
endclass
In reply to peter:
The run_phases of your components are forked by UVM. UVM doesn’t wait for any run_phase tasks to complete, instead it waits until there are no more run phase objections and then ends the simulation.
This can be usefully utilized by having code that you want to run as long as the simulation continues, but you don’t want this code to prevent the simulation from ending, in and of itself.
For example, you might initiate a thread of random background bus traffic in your test. It is a thread that will run forever. You don’t want that to prevent your test from ending, however as long as the test is running you want the traffic to continue.
According your explanation if my parallel sequence takes more time then main sequence so i have to put raise and drop objection in parallel sequence body task to complete parallel sequence
`timescale 1ns/1ns
import uvm_pkg::*;
`include "uvm_macros.svh"
class my_item extends uvm_sequence_item;
`uvm_object_utils(my_item)
function new(string name = "my_item");
super.new(name);
endfunction
endclass
class parallel_seq extends uvm_sequence #(my_item);
`uvm_object_utils(parallel_seq)
function new(string name = "parallel_seq");
super.new(name);
endfunction
task body();
uvm_phase phase = get_starting_phase();
if (phase != null)
phase.raise_objection(this, "parallel_seq starting");
`uvm_info(get_type_name(), "parallel_seq is running...", UVM_MEDIUM)
#50ns;
`uvm_info(get_type_name(), "parallel_seq completed.", UVM_MEDIUM)
if (phase != null)
phase.drop_objection(this, "parallel_seq done");
endtask
endclass
class main_seq extends uvm_sequence #(my_item);
`uvm_object_utils(main_seq)
function new(string name = "main_seq");
super.new(name);
endfunction
task body();
`uvm_info(get_type_name(), "main_seq starting...", UVM_MEDIUM)
fork
begin
parallel_seq pseq = parallel_seq::type_id::create("pseq");
pseq.start(m_sequencer);
end
join_none
// Main sequence work
#49ns;
`uvm_info(get_type_name(), "main_seq completed.", UVM_MEDIUM)
endtask
endclass
class my_driver extends uvm_driver #(my_item);
`uvm_component_utils(my_driver)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
`uvm_info(get_type_name(), "Item received", UVM_MEDIUM)
seq_item_port.item_done();
end
endtask
endclass
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_driver drv;
uvm_sequencer #(my_item) seqr;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = my_driver::type_id::create("drv", this);
seqr = uvm_sequencer#(my_item)::type_id::create("seqr", this);
endfunction
function void connect_phase(uvm_phase phase);
drv.seq_item_port.connect(seqr.seq_item_export);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = my_env::type_id::create("env", this);
endfunction
task run_phase(uvm_phase phase);
main_seq seq;
phase.raise_objection(this, "Test started");
seq = main_seq::type_id::create("main_seq");
seq.start(env.seqr);
phase.drop_objection(this, "Test completed");
endtask
endclass
module top;
initial begin
run_test("my_test");
end
endmodule
in the above code i gave parallel sequence time 50 ns and main sequence 49ns in output i got warning and parallel sequence is not completed
# UVM_INFO uvm_sequence_objection.sv(52) @ 0: uvm_test_top.env.seqr@@main_seq [main_seq] main_seq starting...
# UVM_INFO uvm_sequence_objection.sv(32) @ 0: uvm_test_top.env.seqr@@pseq [parallel_seq] parallel_seq is running...
# UVM_INFO uvm_sequence_objection.sv(64) @ 49: uvm_test_top.env.seqr@@main_seq [main_seq] main_seq completed.
# UVM_WARNING /home/vandan-parekh/Downloads/uvm-core-2020.3.1/src/seq/uvm_sequence_base.svh(993) @ 49: uvm_test_top.env.seqr@@pseq [SEQPRTZMB] The parent process that called start() on sequence 'uvm_test_top.env.seqr.pseq' was terminated without killing the sequence. The kill() method is being automatically triggered.
can you explain me why got warning and what should i do to complete parallel sequence
The time assignments in your sequences are not relevant, because the sequence does not know anything about time. It is a TL-copnstruct. The timing is defined by your driver and the execution time there. And I’m trying to understand why you are using in your main_seq a fork/join_none.
in sequence i take a time as a number of transactions means you can take main sequence doing 49 transactions and parallel seq doing 50 transactions and i am just doing experiment in this code so i write parallel seq inside main seq in fork-join_none and i am trying to understand why it is not run until 50 ns why it is finish in 49ns
This is bevause you are instructing in the body task of your main_seq. The fork/join_none starts the thread, levaes immediately the for/join_none, waits for 49 ns and finishes then.
You can try-out any other time here: