Hi,
I’d like to override the type of items an agent uses using “set_inst_override”. That way I can have generic agent for a bus family and instance the agents without them needing to know which family member they’re dealing with. So I used “set_inst_override(”<path to agent>*,…);".
This worked fine when the agent’s sequences were autonomous but it stopped working when I began using a virtual sequence to drive the sequences.
Investigating I found that the reason is that “do” is creating the item using “ovm_sequence::create_item” which uses “ovm_sequence_item::get_full_name()” to work out the path for override purposes. “ovm_sequence_item::get_full_name()” returns the hierarchy to the sequence via the virtual sequencer (if there is one) and not via the sequencer (and thus the agent) so the override fails.
It doesn’t seem right to me that overriding the type of an item should depend upon how the sequence has been invoked.
I can get around this by creating my own item by calling create_object directly and passing it the correct path (assuming I can find it out reliably) but is this a good idea?
I have created an example by modifying one of Stuart’s virtual sequence examples from here.
The original example doesn’t have agents so I’ve applied the override directly to the sequencer and it’s children, but I don’t think that changes anything materially. There is one test (called “test”) which configures the default sequence for the sequencer to run “simple_seq” and also for the virtual sequencer to run “vsimple_seq” which invokes “simple_seq”.
When “simple_seq” is invoked as the default sequence it’s path is “ovm_test_top.env.sequencer0.simple_seq” and the driver gets “derived_item”, which is as intended
When “simple_seq” is invoked by “vsimple_seq” it’s path is “ovm_test_top.env.vsequencer0.vsimple_seq.s_seq” and the driver gets
“simple_item” which is not as intended.
module test;
`include "ovm.svh"
class simple_item extends ovm_sequence_item;
`ovm_object_utils(simple_item)
function new (string name="simple_item",
ovm_sequencer_base sequencer = null,
ovm_sequence parent_seq = null);
super.new(name, sequencer, parent_seq);
endfunction : new
endclass : simple_item
class derived_item extends simple_item;
`ovm_object_utils(derived_item)
function new (string name="simple_item",
ovm_sequencer_base sequencer = null,
ovm_sequence parent_seq = null);
super.new(name, sequencer, parent_seq);
endfunction : new
endclass : derived_item
class simple_vsequencer extends ovm_virtual_sequencer;
`ovm_declare_sequence_lib
function new (string name, ovm_component parent);
super.new(name, parent);
`ovm_update_sequence_lib
endfunction : new
`ovm_component_utils(simple_vsequencer)
virtual function void build();
super.build();
add_seq_cons_if("foo");
add_seq_cons_if("bar");
endfunction
endclass : simple_vsequencer
class simple_sequencer extends ovm_sequencer;
function new (string name, ovm_component parent);
super.new(name, parent);
`ovm_update_sequence_lib_and_item(simple_item)
endfunction : new
`ovm_declare_sequence_lib
`ovm_component_utils(simple_sequencer)
endclass : simple_sequencer
class simple_seq extends ovm_sequence;
rand int foo;
int bar;
simple_item s_item;
function new(string name="simple_seq",
ovm_sequencer_base sequencer=null,
ovm_sequence parent_seq=null);
super.new(name, sequencer, parent_seq);
endfunction
`ovm_sequence_utils_begin(simple_seq, simple_sequencer)
`ovm_field_int(foo, OVM_ALL_ON)
`ovm_field_int(bar, OVM_ALL_ON)
`ovm_sequence_utils_end
virtual task body();
$display("%0t : simple_seq(%s) body() starting...", $time,get_full_name());
#10;
`ovm_do(s_item)
$display("%0t : simple_seq item done!", $time);
bar = foo + 1;
#40;
endtask
endclass : simple_seq
class vsimple_seq extends ovm_sequence;
simple_seq s_seq;
function new(string name="simple_seq",
ovm_sequencer_base sequencer=null,
ovm_sequence parent_seq=null);
super.new(name, sequencer, parent_seq);
endfunction
`ovm_sequence_utils(vsimple_seq, simple_vsequencer)
virtual task body();
$display("%0t : vsimple_seq body() starting...", $time);
#100;
$display("%0t : vsimple_seq body() doing sequence...", $time);
`ovm_do_seq(s_seq, p_sequencer.seq_cons_if["bar"])
endtask
endclass : vsimple_seq
class simple_driver extends ovm_driver;
ovm_sequence_item item;
function new (string name, ovm_component parent);
super.new(name, parent);
endfunction : new
`ovm_component_utils(simple_driver)
task run();
while(1) begin
#10;
$display("%0t : simple_driver getting next item...", $time);
seq_item_prod_if.get_next_item(item);
$display("%0t : simple_driver got item type %s",$time,item.get_type_name());
seq_item_prod_if.item_done();
end
endtask: run
endclass : simple_driver
class simple_env extends ovm_env;
`ovm_component_utils(simple_env)
function new (string name, ovm_component parent=null);
super.new(name, parent);
endfunction : new
simple_vsequencer vsequencer0;
simple_sequencer sequencer0;
simple_driver driver0;
virtual function void build();
assert($cast(vsequencer0,create_component("simple_vsequencer","vsequencer0")));
assert($cast(sequencer0,create_component("simple_sequencer","sequencer0")));
assert($cast(driver0,create_component("simple_driver","driver0")));
endfunction : build
virtual function void connect();
driver0.seq_item_prod_if.connect_if(sequencer0.seq_item_cons_if);
sequencer0.seq_prod_if.connect_if(vsequencer0.seq_cons_if["bar"]);
endfunction : connect
endclass : simple_env
class test extends ovm_test;
`ovm_component_utils(test)
function new(
string name = "ice_ocp_demo_base_test",
ovm_component parent=null
);
super.new(name,parent);
endfunction : new
simple_env env;
virtual function void build();
set_inst_override("env.sequencer0*","simple_item","derived_item");
set_config_string("env.sequencer0", "default_sequence", "simple_seq");
set_config_string("env.vsequencer0", "default_sequence", "vsimple_seq");
$cast(env, create_component("simple_env", "env"));
super.build();
endfunction : build
task run();
#10000;
$display("%0t : Finishing", $time);
$finish();
endtask : run
endclass : test
initial
begin
$display("Beginning test...");
run_test();
end
endmodule
Cheers
Rob