I came across execute_item
, which seems like a shorthand for sending transaction items directly to a sequencer (and subsequently to the driver). According to the uvm_sequencer
documentation, a temporary sequence is created and run on the transaction item.
// Task: execute_item
//
// Executes the given transaction ~item~ directly on this sequencer. A temporary
// parent sequence is automatically created for the ~item~. There is no capability to
// retrieve responses. If the driver returns responses, they will accumulate in the
// sequencer, eventually causing response overflow unless
// <set_response_queue_error_report_disabled> is called.
extern virtual task execute_item(uvm_sequence_item item);
Naturally, I had to look at the execute_item
implementation to see it in action. It does exactly what is described in the documentation.
task uvm_sequencer_base::execute_item(uvm_sequence_item item);
uvm_sequence_base seq;
seq = new();
item.set_sequencer(this);
item.set_parent_sequence(seq);
seq.set_sequencer(this);
seq.start_item(item);
seq.finish_item(item);
endtask
response_queue_error_report_disabled Link to heading
I took a little detour to examine response_queue_error_report_disabled
and how it is used with responses. Essentially, if put_base_response
fails to push into the queue, it will print a UVM error (unless disabled with response_queue_error_report_disabled
).
virtual function void put_base_response(input uvm_sequence_item response);
if ((response_queue_depth == -1) ||
(response_queue.size() < response_queue_depth)) begin
response_queue.push_back(response);
return;
end
if (response_queue_error_report_disabled == 0) begin
uvm_report_error(get_full_name(), "Response queue overflow, response was dropped", UVM_NONE);
end
endfunction
I haven’t traced it fully, but I assume this would be called at some point when put_response
is invoked. Here is an example of driver code that calls put_response
after item_done
.
// get_and_drive
virtual protected task get_and_drive();
@(negedge vif.sig_reset);
forever begin
@(posedge vif.sig_clock);
seq_item_port.get_next_item(req);
$cast(rsp, req.clone());
rsp.set_id_info(req);
drive_transfer(rsp);
seq_item_port.item_done();
seq_item_port.put_response(rsp);
end
endtask : get_and_drive