vhdlfpgamodelsimghdlvhdl-2008

Deallocating after returning line using std.textio ieee library


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.


Solution

  • 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.