Two same tasks drive an interface at the same time, and how to arbitrate it

I have code like below.


task my_test::run_phase(uvm_phase phase);
......
fork
  testReg1();
  testReg2();
join
.....
endtask

task testReg1();
  ......
  my_seq.start(my_sqr);
  ......
endtask

task testReg2();
  ......
  my_seq.start(my_sqr);
  ......
endtask

In the run_phase, two tasks are parallel to execute and both of them have very similar behavior. And they will start the sqr and drive the transaction to the interface (which named A_intf) And the interface A_intf has a protocol that if one transaction is sent on this interface then the next one must be sent after the return data is back.


interface A_intf;
  output logic a_send;
  output logic a_data;
  input logic b_rtn_valid;
  input logic b_rtn_data;
......
endinterface

So here is the question need your help. In the run_phase, The driver will get two transactions at the same time and how to arbitrate it to make sure one is sent first and the other is sent after the first rtn_valid/rtn_data is received (I have a monitor to receive it )

Thank you !!!

In reply to zz8318:

The driver will only get one sequence_item at a time from the sequencer. When the driver is finished with the sequence_item it retrieved, it will then get the next sequence_item.

Why do you think that the driver will get two sequence_items at the same time?

In reply to cgales:

Yes, I know the driver will get first item and then get next one. But what I need is the next one is driven to the interface after the first return_data is back on this interface.

In reply to zz8318:

It’s still not clear what you are trying to accomplish. The driver will determine when the first sequence_item is complete and get the next sequence_item. If it needs to wait for return_data, then it should wait for return_data. If there is something else that indicates the completion of the first transaction, then the driver should wait for that.

In reply to cgales:

Firstly if we don’t consider the case with the return_valid/return_data, it will be easier. For example, two tasks will send the transactions to the same driver at the same point. The driver will get one of them and drive it into the interface and drive the other when the previous one is finished.

But here is the case which is a little bit complicated, the interface protocol is like below.
The current transaction to input the send/data is not allowed to send until the previous return_valid/return_data is back. (one send with one return)
So when I use fork-join to execute these two tasks and they will start the sequence at the same point (let say tr1 and tr2). If tr1 is firstly selected then the driver will send tr1. And currently in my testbench the tr2 will be sent as the tr1 is finished. but it was not my expectation. I want to make sure the tr2 is sent after the return_valid/data is back for tr1.

Does it make sense ?

In reply to zz8318:

I still don’t see what your issue is. If the driver waits for return_valid/data to be returned, then completes tr1, then tr2 will be after tr1 and meet your requirements. The transactions shouldn’t be finished until return_valid/data is back.

Perhaps you should show your driver code which shows get_next_item()/item_done() and why you think that things aren’t as you expect.