Are system functions like $sformatf guaranteed safe for use inside recursive functions?

Hello,

I have built a tree data structure out of a node class that I created. Inside the node class, I wrote a recursive “to_string” function that converts the root node to a string by recursing into its children, calling to_string on them, and gluing the results together.

I have discovered that, when using $sformatf to glue the child results together in the top level to_string call, $sformatf appears to be using the wrong value for some variables in the top level. Specifically, sformatf is getting the value “” for key and json variables instead of their true values. If I replace the $sformatf call with string concatenation operators, the code behaves as desired. I have tried peppering the code with the “automatic” keyword to no avail.


function node::to_string();
    string json = "{";
    string key;

    foreach(this.children_aa[key])
        json = $sformatf("%s\"%s\":%s,", json, key, this.children_aa[key].to_string());

    // remove a comma from end of json

    json = {json, "}"};
endfunction

So, my question is, should I be able to use $sformatf in an automatic recursive function? My second question is, where is this code implemented? Is it vendor specific, or is it part of the system-verilog standard codebase? (I apologize if my word choice is poor here. I am uneducated)

In reply to dzsaska:

SystemVerilog is language specification and each vendor has its own implementation.

If this function is a class method its lifetime is always automatic.

I tried the complete example below and it worked for me on 3 different SystemVerilog simulators. So I think you may have a vendor specific issue that should be reported to them.

module top;
  int list[$] = '{1,2,3,4,5};
  function automatic string sf(int list[$]);
    if (list.size() == 0)
          return "";
        else begin
          int n;
          n = list.pop_front();
          return $sformatf("%0d ,%s",n,sf(list));
        end
        endfunction     
  initial $display(sf(list));        
endmodule