IEEE 200X Fast Track Change Proposal ID: FT05 Proposer: Jim Lewis (jim@synthworks.com) Updated: David Bishop (dbishop@vhdl.org) Status: Open Proposed: 1-Jan-2003 Analyzed: Date Resolved: Date Enhancement Summary: Add to_string, to_hstring, to_ostring Related issues: Also discussed in std_1164. Relevant LRM section: Enhancement Detail: ---------------------------- Add conversion functions to std.textio that convert from a standard type to type string. Procedures should support formatting similar to std.textio.write. This permits printing of useful messages with assert/report: assert (ExpectedVal = ReadVal) report "In ... Expected Value /= Read Value. Expected = " & to_string(ExpectedVal) & " Read = " & to_string(ReadVal)) severity error ; It also allows usage of VHDL-93 write(, ) in a single print line statement: write(Output, "%%%ERROR data value miscompare in CpuModel." & NL & " Actual data value = " & to_hstring(Data) & NL & " Expected data value = " & to_hstring(ExpData) & NL & " at time: " & to_string(now, right, 12) ) ; To package std.standard we will add the two following impure functions: -- Note that these two functions are not portable impure function NL return string; -- Returns a new line (CR on UNIX, CR LF on PC) impure function SIM_RESOLUTION return delay_length; -- Returns the simulator resolution A function named "justify" shall be created to justify a string to the left or right, and to specify a string width. This function will be called by the "to_string" functions. If the width of the string is larger than the requested width, then the string is returned without being changed. If the width is wider than the string then spaces will be added to the left or right depending on the justified parameter. The parameter names and types used in this function will be the same as those use in the write procedure. "to_string" functions shall also be created for all of the data types which exist in packages std.standard and std.textio. All of these functions will call a "justify" function which and resize a string and/or justify it right or left. These functions will have a similar interface to the std.textio.write functions alread existing. For the "to_string(real)" function will be overloaded with a version with an extra parameter will be added called "format". If format will be assumed to be a C type real number formating string. Allowed will be "%6.2f", "%e", "%E", "%g" and all possible combinations which are allowed in the C printf command (ISO/IEC 9899:1990). Examples: a := 52.5; to_string (a) will return real'image(a) to_string (VALUE => a, format => "%f") will return "52.5" to_string (VALUE => a, format => "%5.2f") will return "52.50" to_string (VALUE => a, format => "%E") will return "5.250000E+01" to_string (VALUE => a, format => "%6.2e") will return "5.25e+01" to_string (VALUE => (a*10.0), format => "%g") will return "525" For the "to_string(time)" function an extra parameter will be added called "resolution". This will default to the deferred constant "Sim_Resolution" which is from the packages std.standard, and will denote the current simulation resolution. If a resolution is passed which is not the default resolution, then the time will be returned in the units of that resolution. If a resolution is passed which is less than the simulation resolution, then "0 ns" will be returned. Analysis: ---------------------------- The proposer suggests adding functions to convert values of predefined types to strings. While std.textio already provides such operations, they are oriented towards file I/O, and are somewhat cumbersome to use in other contexts. Specifically, they are procedures that make use of dynamically allocated strings, imposing both a performance and a usability overhead. The proposer suggests that functions yielding string representations would be simpler to use and more flexible. One approach would be to explicitly declare conversion functions for predefined and other types. Such functions could have signatures that mirror the write operations in td.textio. A prototype of such declarations has been developed (attrib. David Biship): package to_string_prototype is function justify ( VALUE : STRING; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0) return STRING; -- Preferred declarations function to_string ( VALUE : BIT_VECTOR; JUSTIFIED : SIDE := RIGHT; FIELD : WIDTH := 0 ) return string ; alias to_bstring is to_string [BIT_VECTOR, SIDE, WIDTH return STRING]; function to_hstring ( VALUE : BIT_VECTOR; JUSTIFIED : SIDE := RIGHT; FIELD : WIDTH := 0 ) return string ; function to_ostring ( VALUE : BIT_VECTOR; JUSTIFIED : SIDE := RIGHT; FIELD : WIDTH := 0 ) return string ; -- to_string functions for the type from std.standard function to_string ( VALUE : INTEGER; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : BIT; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : BOOLEAN; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : SEVERITY_LEVEL; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : FILE_OPEN_KIND; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : FILE_OPEN_STATUS; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; function to_string ( VALUE : SIDE; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0 ) return STRING ; -- Similar to the "write (real)" function function to_string ( VALUE : REAL; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0; DIGITS : NATURAL := 0 ) return STRING ; -- Format is similar to the C printf format function to_string ( VALUE : REAL; format : STRING ) return STRING ; -- similar to the "write (time)" function function to_string ( VALUE : TIME; JUSTIFIED : SIDE := right; FIELD : WIDTH := 0; UNIT : TIME := ns ) return STRING ; end to_string_prototype ; The prototype includes overloaded versions of to_string for each of the explicitly defined types in std.standard and std.textio. It also includes to_bstring, to_ostring and to_hstring functions that yield binary, octal and hexadecimal representations of bit vectors, and a version of to_string for REAL that adopts C printf formatting conventions. While this approach is satisfactory for models that just use predefined types, it does not allow for models that define new types, including composite types. Such models, particularly testbenches, would benefit from implicit declaration of conversion functions for all declared types. Implicit conversion functions could be specified for all types by extending the definition of the string representation of values of types that is already provided in 14.3 (page 215), as follows: - For a value of an enumeration type: - If the value is a character literal, the character without the enclosing quotation mark characters. - If the value is an identifier, the identifier. - For a value of an integer type, decimal literal, optionally preceded by a sign with no intervening space or format effector characters. - For a value of a physical type, a physical literal in which the abstract literal is a decimal literal, optionally preceded by a sign with no intervening space or format effector characters. - For a value of a floating point type, a decimal literal in which the decimal point is present, optionally preceded by a sign with no intervening space or format effector characters. - For a value that is of a one-dimensional array type whose element type is a character type and that contains only elements that are character values, a string literal without the enclosing double quotation marks and without doubling of any double quotation mark elements. - For a value of a composite type other than a value described by the previous item, an aggregate in which each scalar subelement is represented by its string representation. - For a value of an access type: - If the value is null, the null literal in lowercase. - Otherwise, an implementation-defined representation of the access value that is distinct for each distinct access value. - For a file type, there is no string representation. - For a protected type, there is no string representation. When forming the string representation for a WRITE procedure in STD.TEXTIO or for an implicitly defined to_string operation: - Letters in an identifier or the null literal are in lowercase. - For a value of an integer type, the decimal literal is an integer and there is no exponent. - For a value of a physical type, the decimal literal is an integer, there is no exponent, and the unit name is the simple name of the primary unit of the physical type. - For a value of a floating point type, the decimal literal is in standard form consisting of a normalized mantissa and an exponent in which the sign is present and the 'e' is in lowercase. - There are no insignificant leading or trailing zeros in a decimal literal. - There is no sign preceding the string representation of a non-negative value of an integer, physical or floating point type. - In an aggregate, all element associations are positional, each comma is followed by exactly one space character, and no space character follows each opening parenthesis character nor preceeds each closing parenthesis character. Given this revised definition of the string representation of a type, the to_string function could be implicitly declared for each declared type T, other than a file type or protected type. The implicit declaration of to_string would be function TO_STRING ( VALUE: T ) return STD.STANDARD.STRING; The result yielded by the function would be the string representation of the actual parameter value. By declaring the function in this way, there is no dependence on types declared in STD.TEXTIO. Justification of string values can be done using the proposed JUSTIFY function. Moreover, the to_string functions can be used as conversion functions (eg, in association lists). This implicit declaration of to_string handles most of the required cases. Where specific formatting is required, overloaded versions can be declared explicitly. This would include: -- Version to do C-style formatting for real function TO_STRING ( VALUE: REAL; FORMAT: STRING ) return STRING; -- Version to do textio-style formatting for real function TO_STRING ( VALUE: REAL; DIGITS: NATURAL ) return STRING; -- Version to do textio-style formatting for time function TO_STRING ( VALUE: TIME; UNIT : TIME ) return STRING; -- Versions to format bit vectors in given radices alias TO_BSTRING is TO_STRING [BIT_VECTOR return STRING]; function TO_OSTRING ( VALUE: BIT_VECTOR ) return STRING; function TO_HSTRING ( VALUE: BIT_VECTOR ) return STRING; Resolution: ----------------------------