Hi, I’m quite a bit confused about the using get_next_item and item_done methods in the driver With/Without RSP packet.
Basically, one of the approach in Sequence-Driver-Sequencer communication is the using get_next_item and item_done methods in the driver.
Especially, In Using get_next_item and item_done methods in the driver, I can get the response without rsp.
This is the example without get_response(req) and rsp packet.
But I can get the value of “req.rsp_b” well. why do I need get_response() approach?
//Driver
class driver extends uvm_driver#(seq_item);
`uvm_component_utils(driver)
function new(string name = "driver", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
task run_phase (uvm_phase phase);
forever begin
seq_item req;
seq_item rsp;
seq_item_port.get_next_item(req);
void'(req.randomize());
#50;
req.rsp_b = 1;
seq_item_port.item_done(req);
end
endtask
endclass
class base_seq extends uvm_sequence #(seq_item);
seq_item req;
`uvm_object_utils(base_seq)
function new (string name = "base_seq");
super.new(name);
endfunction
task body();
req = seq_item::type_id::create("req");
wait_for_grant();
assert(req.randomize());
send_request(req);
wait_for_item_done();
// get_response(req);
`uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", req.rsp_b), UVM_LOW);
endtask
endclass
The below is a blocking example to check that the get_response() will block until a response is received.
So I commented out “rsp.rsp_b=1” in the driver to see the blocking.
class driver extends uvm_driver#(seq_item);
`uvm_component_utils(driver)
seq_item req;
seq_item rsp;
function new(string name = "driver", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
task run_phase (uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
void'(req.randomize());
#50;
$cast(rsp, req.clone());
rsp.set_id_info(req);
// rsp.rsp_b = 1;
seq_item_port.item_done(rsp);
end
endtask
endclass
`include "uvm_macros.svh"
import uvm_pkg::*;
`include "seq_item.sv"
`include "sequencer.sv"
`include "driver.sv"
`include "agent.sv"
`include "env.sv"
class base_seq extends uvm_sequence #(seq_item);
seq_item req;
seq_item rsp;
`uvm_object_utils(base_seq)
function new (string name = "base_seq");
super.new(name);
endfunction
task body();
req = seq_item::type_id::create("req");
wait_for_grant();
assert(req.randomize());
send_request(req);
wait_for_item_done();
get_response(rsp); // Block until a response is received
`uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", rsp.rsp_b), UVM_LOW);
endtask
endclass
Unexpectedly, I don’t see it blocking as expected.
I’m confused that I think I don’t need a get_response() to get a response from slave.
Get_response() also doesn’t blocking work.