Hello Everyone,
Good day.
I am creating a testbench that has a structure shown below and am encountering errors perhaps due to the multi-layered virtual sequencer controlling both non-virtual sub sequencers and a virtual sub sequencer. Config's not shown.
<start of diagram>
.------------------------------------------------------.
| my_test |
| .--------------------------------------------------. |
| | sequences | |
| '--------------------------------------------------' |
| .--------------------------------------------------. |
| | my_env | |
| '--------------------------------------------------' |
'/----------------------------------------------------\'
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
.----------------------------------------------------------------------------------------------------.
| my_env |
| .------------------------. |
| | my_virtual_sequencer | |
| '------------------------' |
| .-----------------------------------. .----------------------------. .---------------------------. |
| | sub_virtual_agent | | sub_agent_a | | sub_agent_b | |
| | .-------------------------------. | | .------------------------. | | .-----------------------. | |
| | | sub_virtual_sequencer | | | | sub_sequencer_a | | | | sub_sequencer_b | | |
| | '-------------------------------' | | '------------------------' | | '-----------------------' | |
| | .-------------------------. | | .------------------------. | | .-----------------------. | |
| | | sub_agent_3 | | | | driver_a | | | | driver_b | | |
| | .-------------------------. | | | '------------------------' | | '-----------------------' | |
| | | sub_agent_2 | | | | .------------------------. | | .-----------------------. | |
| | .---------------------------. | | | | | monitor_a | | | | monitor_b | | |
| | | sub_agent_1 | | | | | '------------------------' | | '-----------------------' | |
| | | .-----------------------. | | | | '----------------------------' '---------------------------' |
| | | | sub_sequencer_1 | | | | | |
| | | '-----------------------' | | | | |
| | | .-----------------------. | | | | |
| | | | driver_1 | | | | | |
| | | '-----------------------' | | | | |
| | | .-----------------------. | | | | |
| | | | monitor_1 | | |-' | |
| | | '-----------------------' |-' | |
| | '---------------------------' | |
| '-----------------------------------' |
'----------------------------------------------------------------------------------------------------'
<end of diagram>
1) my_base_sequence (from w/c my_sequence_1 is extend)
<start snip>
class my_base_sequence extends uvm_sequence #(my_sequence_item);
`uvm_object_utils(my_base_sequence)
`uvm_declare_p_sequencer(sub_sequencer_1)
function new (string name ="my_base_sequence");
super.new(name);
endfunction
virtual task pre_start();
if(get_parent_sequence() == null && starting_phase != null)
starting_phase.raise_objection(get_sequencer());
else
`uvm_error(get_type_name(), "starting_phase is null")
endtask
virtual task post_start();
if(get_parent_sequence() == null && starting_phase != null)
starting_phase.drop_objection(get_sequencer());
endtask
endclass
<end snip>
2) my_virtual_sequence
<start snip>
class my_virtual_sequence extends uvm_sequence;
my_sequence_1 i_my_sequence_1;
`uvm_object_utils(my_virtual_sequence)
`uvm_declare_p_sequencer(my_virtual_sequencer)
virtual task body();
`uvm_do_on(i_my_sequence_1, p_sequencer.i_sub_virtual_sequencer.i_sub_sequencer_1);
endtask
endclass
<end snip>
3) my_virtual_sequencer
<start snip>
class my_virtual_sequencer extends uvm_sequencer;
sub_virtual_sequencer i_sub_virtual_sequencer;
sub_sequencer_a i_sub_sequencer_a;
sub_sequencer_b i_sub_sequencer_b;
`uvm_component_utils(my_virtual_sequencer)
function new (string name = "my_virtual_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
i_sub_virtual_sequencer = sub_virtual_sequencer::type_id::create("i_sub_virtual_sequencer",this);
i_sub_sequencer_a = sub_sequencer_a::type_id::create("i_sub_sequencer_a",this);
i_sub_sequencer_b = sub_sequencer_b::type_id::create("i_sub_sequencer_b",this);
endfunction
endclass
<end snip>
4) my_env
<start snip>
class my_env extends uvm_env;
my_virtual_sequencer i_my_virtual_sequencer;
sub_virtual_agent i_sub_virtual_agent;
sub_agent_a i_sub_agent_a;
sub_agent_b i_sub_agent_b;
`uvm_component_utils(my_env);
extern function new (string name = "my_env", uvm_component parent = null);
extern function void build_phase (uvm_phase phase);
extern function void connect_phase (uvm_phase phase);
endclass
function my_env::new(string name = "my_env",uvm_component parent = null);
super.new(name, parent);
endfunction
function void my_env::build_phase(uvm_phase phase);
super.build_phase(phase);
i_sub_virtual_agent = sub_virtual_agent::type_id::create("i_sub_virtual_agent",this);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_sub_virtual_agent.i_sub_virtual_sequencer.i_sub_sequencer_1.main_phase","default_sequence",null);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_sub_virtual_agent.i_sub_virtual_sequencer.i_sub_sequencer_2.main_phase","default_sequence",null);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_sub_agent_a.i_sub_sequencer_a.main_phase", "default_sequence",null);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_sub_agent_b.i_sub_sequencer_b.main_phase", "default_sequence",null);
endfunction
function void my_env::connect_phase(uvm_phase phase);
super.connect_phase(phase);
i_my_virtual_sequencer.i_sub_virtual_sequencer.i_sub_sequencer_1 = i_sub_virtual_agent.i_sub_virtual_sequencer.i_sub_sequencer_1;
i_my_virtual_sequencer.i_sub_virtual_sequencer.i_sub_sequencer_2 = i_sub_virtual_agent.i_sub_virtual_sequencer.i_sub_sequencer_2;
i_my_virtual_sequencer.i_sub_virtual_sequencer.i_sub_sequencer_3 = i_sub_virtual_agent.i_sub_virtual_sequencer.i_sub_sequencer_3;
i_my_virtual_sequencer.i_sub_sequencer_a = i_sub_agent_a.i_sub_sequencer_a;
i_my_virtual_sequencer.i_sub_sequencer_b = i_sub_agent_a.i_sub_sequencer_b;
endfunction
<end snip>
5) my_test
<start snip>
class my_test extends uvm_test;
my_env i_my_env;
`uvm_component_utils(my_test)
extern function new (string name = "my_test",uvm_component parent = null);
extern function void build_phase (uvm_phase phase);
endclass
function my_test::new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void my_test::build_phase(uvm_phase phase);
super.build_phase(phase);
i_my_env = my_env::type_id::create("i_my_env",this);
uvm_config_db #(uvm_object_wrapper)::set(this, "i_my_env,i_my_virtual_sequencer.main_phase","default_sequence",my_virtual_sequence::type_id::get());
endfunction
<end snip>
The result of this test run is as follows:
<start snip>
UVM_ERROR /some_path/my_sequence_lib.sv(693) @400000 : uvm_test_top.i_my_env.i_sub_virtual_agent.i_sub_agent_1.i_sub_sequencer_1@@my_virtual_sequence.i_sub_sequence_1 [my_virtual_sequence] starting_phase is null
. . .
UVM_INFO /cad_tools_path/F-2011.12-SP1/etc/uvm/base/uvm_phase.svh(1233) @400000 : reporter [PH_READY_TO_END] Phase 'uvm.uvm_sched.main' (id=2956) PHASE READY TO END
<end snip>
And then it ended w/o running the sub_sequence_1.
The UVM_ERROR above shows that it was unable to get the raise.objection part to run.
Any help/inputs to this is much appreciated.
Thanks,
Martin