Search code examples
system-verilogverificationhdluvm

Null item error when placing factory registration within a function


I'm trying to write a function that creates registers an item with the factory then does some basic operations to that item. The problem I'm having is that when I try to execute this code, I get a null item error.

An example excerpt of the code I'd like to have would be:

modified_sequence_item example_msg_item

function new (string name = ex_sequence);
  super.new(name); 
  create_message(example_msg_item, "example_msg_item", 32'hDEADBEEF);
endfunction

function create_message(modified_sequence_item msg_item, string msg_name, bit[31:0] data);
    msg_item = modified_sequence_item::type_id::create(msg_name);
    msg_item.data_field = data;
endfunction

Unfortunately, this doesn't work. I get the following error:

UVM_FATAL @ 5710: reporter [NullITM] attempting to start a null item from sequence 'main'

However, the following code does work:

modified_sequence_item example_msg_item

function new (string name = ex_sequence);
  super.new(name); 
  example_msg_item = modified_sequence_item::type_id_create("example_msg_item");
  example_msg_item.data_field = 32'hDEADBEEF;
endfunction

Looking at these two bits of code, to me they are nearly identical aside from the actions being nested inside a function in the first bit of code. This leads me to believe the issue is most likely an issue with passing data being the functions.

Does anyone have any recommendations on how I could modify the first code example so that it does not have a null item error?


Solution

  • Two problems with your function declaration:

    • The handle that you are creating inside your function needs to be copied out when exiting the function, so msg_item needs to be declared as an output argument.
    • You forgot to declare the return type as void. Otherwise the default is a 1-bit 4-state result (IEEE Std 1800-2017, section 13.4 Functions: implicit_data_type)

    function void create_message(
                                 output modified_sequence_item msg_item, 
                                 input string msg_name, bit[31:0] data);
      msg_item = modified_sequence_item::type_id::create(msg_name);
      msg_item.data_field = data;
    endfunction