Why try_next_item (sequencer/port/etc) is declared as task?

I can understand get_next_item is a task, as it might block if there is no item available. However, try_next_item would never block. If an item is available, it returns the item, otherwise it returns null. Should it be declared as a function? Similar to get() vs try_get for mailbox.

In reply to eda2k4:

Because the people who designed this part of the UVM (actually from OVM) did not practice their own advice: re-use. Instead of using exiting TLM functionality, they created a completetly separate communication protocol that looks like TLM, but isn’t.

try_next_item does block for a couple of NBA iterations giving the next sequence body a chance to execute.

In reply to dave_59:

It’d be interesting to see how TLM would look like in this case, though. The race condition is always there: the driver wants something from the sequencer, but the ‘body()’ task of the sequence to be run hasn’t been executed yet. Ideally you’d be able to put something like ‘sequencer.driver_can_try()’ and only then allow ‘try_next_item()’, but that probably makes for a clumsy API choice.

In reply to Tudor Timi:

I believe there was a DVCon paper on this suggestion. UVM TLM would need to be enhanced to be more like SystemC TLM and have an update cycle inserted. Hopefully the author or someone remembers and could post a link.