A known problem in VHDL is that using parts of a return statement (e.g to_string(slv(i))'length
) will generate a warning/error on compile. To work around an unknown string length, I tried using the line
type from textio, but I saw that its seen as good practice to use DEALLOCATE(v_print_line);
after beeing done with the line variable.
How would/should I deallocate when the line is used in the return statement of a function?
My example code is:
-- takes in an integer array and returns a string w/ all entries for printing
-- e.g (111, 12, 5555) will be printed: "'111'/'12'/'5555'"
function pretty_print_int_entries(slv : t_integer_array) return string is
variable v_print_line : line;
begin
for i in slv'range loop
if i /= slv'high then
write(v_print_line, "'" & to_string(slv(i)) & "'/");
else
write(v_print_line, "'" & to_string(slv(i)) & "'");
end if;
end loop;
return v_print_line.all;
end function;
Where you can see the line variable is required in the return.
After running the code above I am unsure if the line element is deallocated by itself, or if there is memory still beeing used after beeing done.
For VHDL-2008, I would do the deallocate manually. You can do this as follows. Note that your usage of slv'high will not work unless you know the t_integer_array (should be integer_vector) parameter has direction of to. Note many have asked for slv to be an abbreviation for std_logic_vector, so I would avoid using it as a parameter name - although overloading should allow it - it is just plain confusing to see it used.
-- takes in an integer array and returns a string w/ all entries for printing
-- e.g (111, 12, 5555) will be printed: "'111'/'12'/'5555'"
impure function pretty_print_int_entries(iv: t_integer_array) return string is
alias a_iv : t_integer_array(0 to iv'length-1) is iv ;
variable v_print_line : line;
impure function return_string_and_deallocate return string is
-- constant result : string := v_print_line.all ; -- should work
variable result : string (1 to v_print_line'length) ; -- works in all VHDL sims
begin
result := v_print_line.all ; -- works around simulators that do not support pointer ref in a declarative region
deallocate(v_print_line) ;
return result ;
end function return_string_and_deallocate;
begin
for i in a_iv'range loop
if i /= a_iv'high then
write(v_print_line, "'" & to_string(iv(i)) & "'/");
else
write(v_print_line, "'" & to_string(iv(i)) & "'");
end if;
end loop;
return return_string_and_deallocate;
end function;
Note that VHDL-2019 has a to_string function that does this for integer_vector. I think it may use ',' as the delimiter rather than '/' and does not decorate with the single quotes.
OSVVM library works around this type of issues by creating a VHDL-2008 and a VHDL-2019 version of our LanguageSupport2019Pkg. We have an implemenation similar to the above for VHDL-2008 to_string and use the VHDL-2019 version for tools that support it.