Nothing new in this post but just wanted to put together what i was going through yday about the sequences/sequencers and how they are started:
so we will have a sequence written something like
class random_seq extends uvm_sequence;
`uvm_object_utils(random_seq)
::::
::::
endclass:random_seq
and in the test we will start the sequence by using uvm_config_db set method, something like:
configuration by type:
uvm_config_db#(uvm_object_wrapper)::set(this, "m_tb.m_agent.m_sequencer.main_phase", "default_sequence", random_seq::get_type());
or something like:
Configuration by instance:
random_seq m_rand_seq_inst;
m_rand_seq_inst = new("m_rand_seq_inst");
uvm_config_db#(uvm_sequence_base)::set(this, "m_tb.m_agent.m_sequencer.main_phase", "default_sequence", m_rand_seq_inst);
above setting will call the following task from the uvm_sequencer_base class and it is called in " protected virtual function void execute" function of uvm_task_phase class.
function void uvm_sequencer_base::start_phase_sequence(uvm_phase phase);
uvm_object_wrapper wrapper;
.......
seq.start(this);
the execute function is called inside
function void m_traverse(uvm_component comp,
uvm_phase phase,
uvm_phase_state state);
case (state)
....
so we will have a sequence written something like
class random_seq extends uvm_sequence;
`uvm_object_utils(random_seq)
::::
::::
endclass:random_seq
and in the test we will start the sequence by using uvm_config_db set method, something like:
configuration by type:
uvm_config_db#(uvm_object_wrapper)::set(this, "m_tb.m_agent.m_sequencer.main_phase", "default_sequence", random_seq::get_type());
or something like:
Configuration by instance:
random_seq m_rand_seq_inst;
m_rand_seq_inst = new("m_rand_seq_inst");
uvm_config_db#(uvm_sequence_base)::set(this, "m_tb.m_agent.m_sequencer.main_phase", "default_sequence", m_rand_seq_inst);
above setting will call the following task from the uvm_sequencer_base class and it is called in " protected virtual function void execute" function of uvm_task_phase class.
function void uvm_sequencer_base::start_phase_sequence(uvm_phase phase);
uvm_object_wrapper wrapper;
.......
seq.start(this);
......
endfunction
protected virtual function void execute(uvm_component comp,
uvm_phase phase);
...............
if ($cast(seqr,comp)) // Only if the component is sequencer then the start_phase_sequence is called
// otherwise its ignored.
seqr.start_phase_sequence(phase);
...............
endfunction
function void m_traverse(uvm_component comp,
uvm_phase phase,
uvm_phase_state state);
case (state)
....
UVM_PHASE_EXECUTING: begin
....
ph.execute(comp, phase);
....
end
....
endcase
endfunction
m_tranverse is called in traverse function of uvm_task_phase
virtual function void traverse(uvm_component comp,
uvm_phase phase,
uvm_phase_state state);
phase.m_num_procs_not_yet_returned = 0;
m_traverse(comp, phase, state);
endfunction
which is called in uvm_phase s task
task uvm_phase::execute_phase();
......
m_state = UVM_PHASE_STARTED;
m_imp.traverse(top,this,UVM_PHASE_STARTED);
#0; // LET ANY WAITERS WAKE UP
.......
endtask
and the execute+phase is called as a part of m_run_phases task of uvm_phase
task uvm_phase::m_run_phases();
uvm_root top = uvm_root::get();
.....
fork
begin
phase.execute_phase();
end
join_none
.....
endtask
this m_run_phases task is called in run_test task of uvm_root from which all the tests are run and all the components are instantiated.
task uvm_root::run_test(string test_name="");
................
// phase runner, isolated from calling process
fork begin
// spawn the phase runner task
phase_runner_proc = process::self();
uvm_phase::m_run_phases();
end
join_none
...............
endtask
and the run_test with which the testcase is run
the explanation for run_test:
// Phases all components through all registered phases. If the optional
// test_name argument is provided, or if a command-line plusarg,
// +UVM_TESTNAME=TEST_NAME, is found, then the specified component is created
// just prior to phasing. The test may contain new verification components or
// the entire testbench, in which case the test and testbench can be chosen from
// the command line without forcing recompilation. If the global (package)
// variable, finish_on_completion, is set, then $finish is called after
// phasing completes.
other notes:
uvm_object --> uvm_phase --> uvm_task_phase --> all the uvm_runtime_phases (reset_phase,configure_phase ....)
uvm_phase has the prototype for all the tasks required while executing a phase and uvm_task_phase is derived from it which has some functionality required for executing the phases (things which are common across the phases)