// If a sequence_item has already been requested, then get_next_item()
// should not be called again until item_done() has been called.
if (get_next_item_called == 1)
uvm_report_error(get_full_name(),
“Get_next_item called twice without item_done or get in between”, UVM_NONE);
if (!sequence_item_requested)
m_select_sequence();
// Set flag indicating that the item has been requested to ensure that item_done or get
// is called between requests
sequence_item_requested = 1;
get_next_item_called = 1;
m_req_fifo.peek(t);
endtask
The above task is implemented in the baseclass of uvm_sequencer. they have implemented the get_next_item method using peek method(if you see the above code). peek is a method which gives the copy of the value and the value will be remained in the mailbox. the size of req_fifo is 1. once a packet has been put inside the req_fifo until i get the packet out i cannot put any other packet. if this is the case, how the hand shaking between driver and sequencer is happening for multiple packets. can anyone give me clarity.?
No, my question is how the driver getting the next packet when the previous packet still there in req_fifo. Peek is a mailbox method. Peek method will give copy of the packet but the packet will be left there inside req_fifo. When a packet is already there inside the req_fifo, how the driver is getting another new packet (using peek method we can’t get the packet out. It’s just takes the copy of packet).
As the Cookbook chapter points out, you don’t use get_next_item() when you want to get multiple sequence items. You use get() which will remove the item from the queue.
If you use get_next_item(), you need to use item_done() to remove the item from the queue.
quick question, if get_next_item is a task inside uvm_sequencer. then how can we address it as seq_item_export.get_next_item(). This is the way we use get-next_item() in most cases ie normal cases that are non pipelined.
This because the uvm_sequencer ha a ‘seq_item_export’ as an interface. We are calling in the driver exactly seq_item_export.get_next_item(req) to retrieve a sequence_item from the sequencer.
I am not exactly following what you meant. seq_item_export is a pull port (as shown below). if get_next_item is a task inside uvm_sequencer then shouldnt get_next_item be called as sequencer.get_next_item(), why does seq_item_export.get_next_item() work correctly as well?
Looks like you are not familiar with TL communication. Units play different roles. The sequencer is a pssive unit and cannot act, but the driver is an active unit and will retrieve a sequence_item from the sequencer calling seq_item_export.get_next_item(req).
The driver does not have a handle to the sequencer. TLM is layer of abstraction that provides a standard way for components to communicate without any knowledge of the component they are communicating with. A “port” is the initiator or caller, and the “export” is the provider, or callee. In this scenario the sequencer is providing the implementation of get_next_item() and exporting a handle to the port in the driver through the seq_item_export
Hi Dave, thanks for the reply. I am referencing to the concept of sequence layering in UVM. where we use translator sequence for establishing the layer.
In non-layering scenario we use seq_item_export.get_next_iyem(), thats okay but in translator seq we use get_next_item differently. as in the snip shown. What i dont get is how can get_next_item be used differently in layering vs non-layering scenarios.