Search code examples
system-veriloguvm

uvm register write is stuck and never return


I have some block of register along with corresponding register adaptor setup to translate into some bus protocol.

When I called the write method to one of my register, I could see the transaction going on, and driver complete its job, but write is stuck somewhere.

Please see excerpt of driver and sequence below:

// ...uvm driver
forever begin
  seq_item_port.get_next_item(req);
  $display("DEBUG A");
  // ... do transaction
  seq_item_port.item_done();
  $display("DEBUG B");
end

// ... sequence
$display("START WRITE");
my_reg_block.my_reg1.write(
$display("DONE WRITE");

The result:

START WRITE
DEBUG A
DEBUG B

and then simulation stuck there - I never see DONE WRITE.

I am quite sure all the connect, set_sequencer has been made properly - otherwise my driver shouldn't see transaction in the first place. And this is pretty simple test - only doing that write.

Any idea why it is stuck in register write method eventhough the driver seems to have completed the transaction? I probably missed something.


Solution

  • In uvm_reg_map::do_bus_write(...) there's the following code snippet that handles the bus request for a register access:

      bus_req.set_sequencer(sequencer);
      rw.parent.start_item(bus_req,rw.prior);
    
      if (rw.parent != null && i == 0)
        rw.parent.mid_do(rw);
    
      rw.parent.finish_item(bus_req);
      bus_req.end_event.wait_on();
    

    Notice the end_event.wait_on(). This event is normally triggered on a sequence item by the sequencer, once item_done() was called and finish_item() returns:

    `ifndef UVM_DISABLE_AUTO_ITEM_RECORDING
    sequencer.end_tr(item);
    `endif
    

    It's possible to turn this off using the define, which is what I guess is happening in your case.