-1

In System Verilog UVM, the interface present in TLM ports for communication between sequences and drivers (uvm_sqr_if_base) offers flexibility. For pulling requests, I'll summarize the four options in this table:

                  blocking   item_done
get_next_item()      yes        no
try_next_item()       no        no
          get()      yes       yes
         peek()      yes        no

... where blocking indicates that if you call the method, but no sequence is ready to provide data, then the task will BLOCK and wait until data is ready and can and will be returned.

... where item_done indicates that the method also calls item_done() after successfully pulling an item from the sequence.

What's the difference between peek() and get_next_item() then?

Consider these two code snippets from two imaginary drivers ...

  while(1) begin: loop1                          while(1) begin: loop2
    seq_item_port.get_next_item(req);              seq_item_port.peek(req);
    process(req);                                  process(req);
    seq_item_port.item_done();                     seq_item_port.item_done();
  end: loop1                                     end: loop2

What's the difference? Why are there two methods for accomplishing the same thing? It doesn't seem to be TLM1 vs TLM2 styles.

EDIT:

To answer the point below. I had looked at the source code before asking this question. In fact, the LANGUAGE differs only slightly, the code seems to do exactly the same thing. What's the point? What am I missing?

  // Task: get_next_item
  //
  // Retrieves the next available item from a sequence.  The call will block
  // until an item is available.  The following steps occur on this call:
  //
  // 1 - Arbitrate among requesting, unlocked, relevant sequences - choose the
  //     highest priority sequence based on the current sequencer arbitration
  //     mode. If no sequence is available, wait for a requesting unlocked
  //     relevant sequence,  then re-arbitrate.
  // 2 - The chosen sequence will return from wait_for_grant
  // 3 - The chosen sequence <uvm_sequence_base::pre_do> is called
  // 4 - The chosen sequence item is randomized
  // 5 - The chosen sequence <uvm_sequence_base::post_do> is called
  // 6 - Return with a reference to the item
  //
  // Once <get_next_item> is called, <item_done> must be called to indicate the
  // completion of the request to the sequencer.  This will remove the request
  // item from the sequencer FIFO.

vs.

  // Task: peek
  //
  // Returns the current request item if one is in the sequencer FIFO.  If no
  // item is in the FIFO, then the call will block until the sequencer has a new
  // request. The following steps will occur if the sequencer FIFO is empty:
  //
  // 1 - Arbitrate among requesting, unlocked, relevant sequences - choose the
  // highest priority sequence based on the current sequencer arbitration mode.
  // If no sequence is available, wait for a requesting unlocked relevant
  // sequence, then re-arbitrate.
  //
  // 2 - The chosen sequence will return from <uvm_sequence_base::wait_for_grant>
  // 3 - The chosen sequence <uvm_sequence_base::pre_do> is called
  // 4 - The chosen sequence item is randomized
  // 5 - The chosen sequence <uvm_sequence_base::post_do> is called
  //
  // Once a request item has been retrieved and is in the sequencer FIFO,
  // subsequent calls to peek will return the same item.  The item will stay in
  // the FIFO until either get or <item_done> is called.
E_net4
  • 27,810
  • 13
  • 101
  • 139
Lance E.T. Compte
  • 932
  • 1
  • 11
  • 33

1 Answers1

1

Peek is definitely from TLM1 style. It gives you the opportunity to look at the next item in the queue without removing it from the queue. This means you have not committed to starting the item. Peeks could be used in two different scenarios.

  1. One-to-Many: You could have multiple drivers, or multiple threads within a single driver doing peeks and then deciding if they want to get the sequence item, or ignore the item. The peak lets you look at the contents of the item before you make a decision to commit to it with a get.
  2. Many-to-one: You could have multiple sequencers connected to the same driver. The driver would take a peek from all its connections and decide which sequencer it wants to commit to.
dave_59
  • 39,096
  • 3
  • 24
  • 63