Jump to content

uvm_send is blocked even after driver executes item_done


Recommended Posts

Hi All,

 

I have a sequence sending a created and randomized item using `uvm_send.

 

The driver receives an item using try_next_item. Upon receiving, it drives the item and calls item_done.

Using debug message after item_done, I can clearly see that item_done is called and returned but `uvm_send in sequence is still blocked and not doing forward to send next item (it implements a loop).

 

Can anyone help me with possible reasons why `uvm_send would not return even when driver has called item_done and come out of item_done.

 

Thanks in advance!

Ninad

Link to comment
Share on other sites

Just off the top of my head, make sure that what you are sending is what actually ends up in the driver. Put a print before `uvm_send and one after try_next_item() and see if the handles match.

 

Hi Tudor,

 

Let me provide pseudo code for details.

 

my_trans_item item;

 

for (n_trans = 0; n_trans < 4; n_trans++) begin

  `uvm_create_on(item, p_sequencer.sequencer_for_item);

  dp.randomize();

  `uvm_send(item);

  /* Later replaced `uvm_send with following:

  start_item(item);

  finish_item(item);

  */

end

 

For 2 out of 4 iterations, the code runs absolutely fine (and data is driven on the DUT interface as expected).

(This probably would answer your question).

For 3rd iteration, `uvm_send is blocked.

In waveforms, I see that complete transaction is driven on DUT interface but `uvm_send does not return.

 

Then I broke `uvm_send in start_item(item) and finish_item(item).

In this case, I see start_item returning but finish_item does not return.

 

Ninad

Link to comment
Share on other sites

What would also be helpful would be to post some code from the driver.

 

Yes. Should have done that earlier :)

 

* driver

forever begin

  seq_item_port.try_next_item(item); 

  if (item == null) begin

    // Drive junk without valid

  end else begin

    fork

      reset_detect();

      begin

      uvm_test_done.raise_objection(this, tID);

      send_to_dut(item);

      seq_item_port.item_done();

      uvm_test_done.drop_objection(this, tID);

      end

    join_any

    disable fork;

  end // if (item == null)

end // forever

Link to comment
Share on other sites

I see there that reset_detect() has the potential to kill the thread that calls item_done() (the one between begin ... end). Have a look if this is the case for you.

 

If you want to interrupt driving on reset, then you should make sure to call item_done() to signal to the sequencer that the item is finished (either driven or discarded in your case) and that a new item can start.

Link to comment
Share on other sites

I see there that reset_detect() has the potential to kill the thread that calls item_done() (the one between begin ... end). Have a look if this is the case for you.

 

If you want to interrupt driving on reset, then you should make sure to call item_done() to signal to the sequencer that the item is finished (either driven or discarded in your case) and that a new item can start.

 

You are correct. It is been taken care of. This is code for reset_detect(). And in waveforms I dont see reset triggering either.

 

    task reset_detect();
 
      wait(vif.rst_n === 1'b1);
      wait(vif.rst_n === 1'b0);
 
      if(uvm_test_done.get_objection_total(this) > 0)
        uvm_test_done.drop_objection(this, tID, uvm_test_done.get_objection_total(this));
      seq_item_port.item_done();
 
    endtask
Link to comment
Share on other sites

  • 1 year later...

Hi,

I got a similar issue but i have checked the sending item and driver ending item, both are similar. Below is the description of my problem. If you guys have any solution please share.

 

I have a task in virtual sequencer which actually randomizes the sequence item and then uses execute_item to send the randomized sequence item to the driver.

The driver receives an item using get_next_item. Upon receiving, it drives the item and calls item_done.
Using debug message after item_done, I can clearly see that item_done is called and returned but execute_item in sequencer is still blocked and not going forward to send next item (it implements a loop).

Can anyone help me with possible reasons why execute_item would not return even when driver has called item_done and come out of item_done.

Below is the code of task in sequencer:
assert(item.randomize());
dc_seqr.execute_item(item);

Below is the code in driver:

forever begin
seq_item_port.get_next_item(item);
$cast(m_transfer,item);
void'(this.begin_tr(m_transfer));
drive_data(m_transfer);
this.end_tr(m_transfer);
seq_item_port.item_done(m_transfer);
end

PS:
execute_item has finish_item() and kept display statements below and above of it and i can find that its hanging at finish_item.
The task is called multiple times and the issue is coming for only recent call and is there are no more calls are happening because its hanging at finish_item.

Thanks in advance!
Avinash.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...