I am trying to use try_next_item() in the driver, but looks like its not working properly.
I tried do dig deeper.
---------ovm_sequencer.svh----------
task try_next_item(output REQ t);
wait_for_sequences();
if (has_do_available() == 0) begin
t = null;
return;
end
get_next_item(t);
endtask // try_next_item
in this code if has_do_available() returns 1, then get_next_item is executed immediately.
In the task get_next_item(), peek is used to access the item; hence this is waits until there is an item available to be sent.
Now
---------ovm_sequencer_base.svh-----------
function bit has_do_available();
foreach (arb_sequence_q[i]) begin
if (arb_sequence_q[i].sequence_ptr.is_relevant() == 1) begin
return (1);
end
end // UNMATCHED !!
return (0);
endfunction
is_relevant task always returns 1.
I am not sure if i have done something wrong.
Did anyone of you found an issue with this?
I am using virtual sequencers. the virtual sequence calls lower sequencer’s sequence, which inturn sends the packet to driver.
The problem i am facing is,
when there is no request available to drive I want to drive default transactions, but by using try_next_item, I am driving only when there is any specific request by the sequence :(:(
Tough to say without more info. Check that the sequencer’s default_sequence is set correctly. When I’m getting sequences I don’t want, I usually forgot to change the default sequence away from its default of ovm_random_sequence.
I am setting default sequence to the virtual sequence at the start of test case.
class basic_test extends core_base_test;
`ovm_component_utils(basic_test)
function new(string name = “basic_test”, ovm_component parent=null);
super.new(name,parent);
endfunction : new
virtual function void build();
set_config_string(“core_tb0.core_dv_env_rtl.core_vseq”, “default_sequence”, “basic_test_vseq”);
super.build();
endfunction : build
task run();
@test_complete;
#200;
global_stop_request();
endtask: run
endclass : basic_test
//-------------------------
In the virtual sequence, I am grabbing both the sequencers
-------virtual sequence—
task body();
//If this sequence is a subsequence in another sequence, then sequencers need not be grabbed
//If this is used as a test case, then as a highest sequence it has to grab the sequencers
if(test_continue == 0)
begin
p_sequencer.read_sequencer.grab(this);
p_sequencer.write_sequencer.grab(this);
end
fork
ovm_do_on(idl_wseq, p_sequencer.write_sequencer); ovm_do_on(idl_rseq, p_sequencer.read_sequencer);
join
//---------
//write 5 times
ovm_create_on(asym_ww, p_sequencer.write_sequencer); asym_ww.con_no_of_txns.constraint_mode(0); asym_ww.no_of_txns = 5;// ovm_send(asym_ww);
//
//read 5 times
ovm_create_on(asym_rw, p_sequencer.read_sequencer); asym_rw.con_no_of_txns.constraint_mode(0); asym_rw.no_of_txns = 5;// ovm_send(asym_rw);
//
endtask: body
//---------virtual sequence end—
So In my read driver, I am using try_next_item
When the write driver is writing, I have no requests on the read domain, hence i want the read driver to just advance idle cycles on the read side.
Instead, what is happening is the driver is just active only when I start some read requests.
What i suspect is, because I am grabbing the sequencers, the internally the sequences are locked to the drivers, once the driver triggers item_done, if the sequencer is locked, it updates its pointers even without any request from the sequencer to the driver.
I might be wrong.