Null Item error when passing data between functions for item registration

I’m trying to write a function that registers an item with the factory than does 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 too 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 it is most likely an issue with passing data being the functions. Data scope is another possibility but as the modified sequence item is declared outside of either function I find that less likely.

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

In reply to Greyspectre:

I’m guessing that you are getting the error message later on in your run phase. This is because you aren’t returning the new example_msg_item back to the caller.

You likely want this:


modified_sequence_item example_msg_item
 
function new (string name = ex_sequence);
  super.new(name); 
  example_msg_item = create_message("example_msg_item", 32'hDEADBEEF);
endfunction
 
 
function modified_sequence_item create_message(string msg_name, bit[31:0] data);
  modified_sequence_item msg_item = modified_sequence_item::type_id::create(msg_name);
  msg_item.data_field = data;
  return msg_item;
endfunction

Also, you should usually have a return value from a function and use the return value to ensure that the function executed properly.