How to arbitrate among different mailboxes?

Hello,

so here is my “problem”, maybe there is something fundamentaly wrong with what I am doing. In my model y have many producers which generate objects and send them to an arbiter through mailboxes. Each producer has ints own mailbox connecting it to the arbiter.

Then I want the arbiter to go throgh all the mailboxes and pick the one that has data with the highest priority.

So basicaly in my arbiter I have a loop that goes through all the mailboxes starting with the one with the highest priority, it the mailbox is empty, it moves on to the next. Conceptually it would be something like:

for ( producer = highest_prio ; producer != lowest_prio ; producer = next ) begin
if (producer.mbox.try_get(object)) begin
do_something_with_the_object
break;
end
end

This for is inside a forever block which has been forked/join_none from the execution thread. I know it’s probably not the most elegant thing but I expected that in the worst of cases the loop would get executed in every delta-time, however what happens is that my simulation freezes at time 0 and nothing else gets done.
I have also tried it with queues and checking for data with queue.size() with the same result.

Anybody can shine some light on this?

Thanks,
Albert.

In reply to arquer:

Consider the case when all MBOX-es have no items, this will get into infinite loop. I suggest you look at uvm_sequencer as it has similar logic (with more customization for priority etc.)

Regards
Srini
www.go2uvm.org

In reply to Srini @ CVCblr.com:

In that case, when there is nothing in any mailbox i would expect simulation to at least not get stuck, since the loop has been forked/join_none from the main thread. Why is this not the case?

*In reply to Srini @ CVCblr.com:*I agree with Srini’s comments: uvm_sequencer does exactly what you are looking for. But if you need to get this working without the UVM, the general algorithm is in this pseudo-code:

forever begin : forever_loop
   foreach (queue[i] or mailbox[i]) begin : wait_loop
      fork a process that blocks with wait(q[i].num >0) or mailbox[i].peek;
      #0 make sure all forks have started so that they can be killed
      kill all other processes that are blocked
      end : wait_loop
   wait fork; 
    foreach (queue[i] or mailbox[i]) begin : arb_loop
       pick  the producer to service
    end : arb_loop
  end :forever_loop

In reply to arquer:
You didn;t show your code, but you are probably in a forever loop with a fork/join
_none. If the forever loop never blocks, you wind up with a zero-delay infinite loop, and time cannot advance.