---- File: PCK_FIO.vhd ---- ---- PCK_FIO: a VHDL package for C-style formatted file output ---- Copyright (C) 1995, 1999 Easics NV ---- ---- This program is free software; you can redistribute it and/or modify ---- it under the terms of the GNU General Public License as published by ---- the Free Software Foundation; either version 1, or (at your option) ---- any later version. ---- ---- This program is distributed in the hope that it will be useful, ---- but WITHOUT ANY WARRANTY; without even the implied warranty of ---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ---- GNU General Public License for more details. ---- ---- You should have received a copy of the GNU General Public License ---- along with this program; if not, write to the Free Software ---- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ---- ---- For suggestions, bug reports, enhancement requests, and info about ---- our design services, you can contact us at the following address: ---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium ---- tel.: +32 16 395 600 fax : +32 16 395 619 ---- e-mail: jand@easics.be (Jan Decaluwe) ---- ---- ---- Revision history: ---- ---- $Source: /tmp/cvsroot/VHDL/lib/PCK_FIO-1.16/PCK_FIO.vhd,v $ ---- $Revision: 1.1 $ ---- $Log: not supported by cvs2svn $ ---- Revision 1.16 1999/04/21 08:28:46 jand ---- Tested with IEEE.numeric_std ---- Small patch for Leapfrog ---- ---- Revision 1.14 1997/07/14 10:16:04 jand ---- prefix/postfix for bits/bitvectors set to empty strings by default ---- ---- Revision 1.13 1997/07/11 17:42:57 jand ---- Corrected Easics address ---- ---- Revision 1.12 1997/07/11 17:38:49 jand ---- Improved prefix/postfix support ---- ---- Revision 1.11 1995/11/15 13:46:02 jand ---- Catched integer'low value in fo for integers ---- ---- Revision 1.10 1995/08/11 16:42:26 jand ---- Reimplemented FIO_FormatExpand as a procedure in an attempt to ---- avoid memory leakage problems in VSS ---- ---- Revision 1.9 1995/08/09 13:47:51 jand ---- Removed array of line trick in fprint for less memory, less ---- CPU time, and more conservatism in general ---- Rearranged FIO_PrintValue call so that fprint remains concise ---- ---- Revision 1.8 1995/08/09 10:32:27 jand ---- Removed fprint_flat to have a single call level ---- Added explicit deallocators of line variables (has strong influence ---- on memory usage in VSS - and possibly CPU time) ---- Redefined 'fo' for type time to make it more portable ---- ---- Revision 1.7 1995/08/07 08:56:04 jand ---- Improved conciseness of fprint argument handling through array of line type ---- ---- Revision 1.6 1995/08/04 18:19:13 jand ---- Increase # arguments from 16 to 32 ---- Corrected bug within fprint 's call to Arg16 ---- Added support for bit format specifier 'b' ---- ---- Revision 1.5 1995/08/02 10:22:37 jand ---- Release 1.1 under GNU ---- ---- Revision 1.4 1995/08/01 11:15:52 jand ---- Added escaping during iteration string read ---- ---- Revision 1.3 1995/08/01 08:23:47 jand ---- Many improvements in robustness, conciseness and coding style ---- ---- Revision 1.2 1995/07/30 16:15:43 jand ---- Improved robustness for release to the world ---- ---- Revision 1.1 1995/07/30 14:21:30 jand ---- Initial revision ---- use STD.TEXTIO.all; library IEEE; use IEEE.std_logic_1164.all; -- signed/unsigned definition: use either std_logic_arith or numeric_std use IEEE.std_logic_arith.all; -- the Synopsys one -- use IEEE.numeric_std.all; package PCK_FIO is -- prefix string for hex output -- VHDL style: "X""" -- Verilog style: "h'" -- C style: "0x" constant FIO_h_PRE: string := "0x"; -- postfix string for hex output -- VHDL style: """" constant FIO_h_POST: string := ""; -- prefix string for bit vector output -- VHDL style: "B""" -- Verilog style: "b'" constant FIO_bv_PRE: string := ""; -- postfix string for bit vector output -- VHDL style: """" constant FIO_bv_POST: string := ""; -- prefix string for bit output -- VHDL style: "'" -- Verilog style: "b'" constant FIO_b_PRE: string := ""; -- postfix string for bit output -- VHDL style: "'" constant FIO_b_POST: string := ""; -- digit width for the string representation of integers constant FIO_d_WIDTH: integer := 10; -- bit width for the string representation of integers constant FIO_b_WIDTH: integer := 32; -- definition of the NIL string (default value for fprint arguments) -- fprint stops consuming arguments at the first NIL argument constant FIO_NIL: string := "\"; procedure fprint (F: out text; L: inout line; Format: in string; A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL ); function fo (Arg: unsigned) return string; function fo (Arg: signed) return string; function fo (Arg: std_logic_vector) return string; function fo (Arg: std_ulogic_vector) return string; function fo (Arg: bit_vector) return string; function fo (Arg: integer) return string; function fo (Arg: std_ulogic) return string; function fo (Arg: bit) return string; function fo (Arg: boolean) return string; function fo (Arg: character) return string; function fo (Arg: string) return string; function fo (Arg: time) return string; procedure FIO_FormatExpand (FMT: inout line; Format: in string; StartPointer: in positive); end PCK_FIO; package body PCK_FIO is -------------------------- -- FIO Warnings support -- -------------------------- procedure FIO_Warning_Fsbla (F: out text; L: inout line; Format: in string; Pointer: in positive) is begin fprint (F, L, "\n** Warning: FIO_PrintLastValue: " & "Format specifier beyond last argument\n"); fprint (F, L, "** in format string: ""%s""\n", Format); fprint (F, L, "** "); for i in 1 to Pointer-1 loop fprint (F, L, "-"); end loop; fprint (F, L, "^\n"); end FIO_Warning_Fsbla; procedure FIO_Warning_Ufs (F: out text; L: inout line; Format: in string; Pointer: in positive; Char: in character) is begin fprint (F, L, "\n** Warning: FIO_PrintArg: " & "Unexpected format specifier '%r'\n", fo(Char)); fprint (F, L, "** in format string: ""%s""\n", Format) ; fprint (F, L, "** "); for i in 1 to Pointer-1 loop fprint (F, L, "-"); end loop; fprint (F, L, "^\n** Assuming 'q' to proceed: "); end FIO_Warning_Ufs; ---------------------------------- -- bit conversion support -- ---------------------------------- type T_bit_map is array(bit) of character; constant C_BIT_MAP: T_bit_map := ('0', '1'); ---------------------------------- -- std_logic conversion support -- ---------------------------------- type T_std_logic_map is array(std_ulogic) of character; constant C_STD_LOGIC_MAP: T_std_logic_map := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); ------------------------------ -- Digit conversion support -- ------------------------------ -- types & constants subtype S_digit_chars is character range '0' to '9'; subtype S_digits is integer range 0 to 9 ; type T_digit_chars_map is array(S_digit_chars) of S_digits; constant C_DIGIT_CHARS_MAP: T_digit_chars_map := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); type T_digits_map is array(S_digits) of S_digit_chars; constant C_DIGITS_MAP: T_digits_map := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); -------------------------------- -- Decimal conversion support -- -------------------------------- function U_To_d (Arg: string) return integer is constant Argument: string(Arg'length downto 1) := Arg; variable Result: integer := 0; begin for i in Argument'range loop case Argument(i) is when '1' => Result := 2**(i-1) + Result; when '0' => null; when others => return(-1); end case; end loop; return (Result); end U_To_d; function S_To_d (Arg: string) return integer is constant Argument: string(Arg'length downto 1) := Arg; variable Result: integer := 0; begin case Argument(Argument'left) is when '1' => Result := - 2**(Argument'left-1); when '0' => Result := 0; when others => return (integer'low); end case; for i in Argument'left-1 downto 1 loop case Argument(i) is when '1' => Result := 2**(i-1) + Result; when '0' => null; when others => return(integer'low); end case; end loop; return (Result); end S_To_d; function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is constant Sign: character := Arg(1); constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length); variable Char: character; variable Result: integer := 0; begin Result := 0; for i in Value'range loop Result := Result * 10; Char := Value(i); if (Char /= ' ') then Result := Result + C_DIGIT_CHARS_MAP(Char); end if; end loop; case Sign is when '-' => return(-Result); when others => return(Result); end case; end I_To_d; function B_To_d (Arg: string(1 to 1)) return integer is begin case Arg is when "1" => return(1); when "0" => return(0); when others => return(-1); end case; end B_To_d; function L_To_d (Arg: string(1 to 1)) return integer is begin case Arg is when "T" => return(1); when others => return(0); end case; end L_To_d; ---------------------------- -- Hex conversion support -- ---------------------------- -- Constants & types constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?"; -- Function to return Hex index of a nibble function U_To_h_Index(Arg: string(4 downto 1)) return integer is variable Index: integer := 0; begin for i in Arg'range loop case Arg(i) is when '1' => Index := 2**(i-1) + Index; when '0' => null; when others => return (17); end case; end loop; return (Index+1); end U_To_h_Index; -- Hex conversion function U_To_h (Arg: string) return string is variable Result: string((Arg'length-1)/4 +1 downto 1); variable ExtArg: string(Result'length*4 downto 1) := (others => '0'); begin ExtArg(Arg'length downto 1) := Arg; for i in Result'range loop Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) )); end loop; return (FIO_h_PRE & Result & FIO_h_POST); end U_To_h; ---------------------------- -- Bit conversion support -- ---------------------------- function L_To_b (Arg: string(1 to 1)) return string is variable Result: string(1 to 1); begin case Arg is when "T" => Result := "1"; when others => Result := "0"; end case; return(FIO_b_PRE & Result & FIO_b_POST); end L_To_b; function I_To_b (Arg: string(1 to FIO_d_WIDTH+1); Justified: side; Width: integer) return string is variable IntValue: integer := I_To_d(Arg); variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' '); variable Sign: character := ' '; constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' '); variable BitWidth: integer range 0 to FIO_b_WIDTH; variable MsPos: integer range 1 to BitValue'length; variable BitValueExtended: string(1 to 2*FIO_b_WIDTH); begin if (IntValue < 0) then Sign := '-'; IntValue := -IntValue; end if; for i in BitValue'reverse_range loop BitValue(i) := C_DIGITS_MAP(IntValue mod 2); IntValue := IntValue / 2; exit when (IntValue = 0); end loop; BitValueExtended := BitValue & Blanks; if (Width = 0) or (Width > FIO_b_WIDTH+1) then BitWidth := FIO_b_WIDTH; else BitWidth := Width-1; end if; if (Justified = RIGHT) then return (FIO_bv_PRE & Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) & FIO_bv_POST); else for i in BitValue'range loop if BitValue(i) /= ' ' then MSPos := i; exit; end if; end loop; return (FIO_bv_PRE & Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) & FIO_bv_POST); end if; end I_To_b; ----------------------------------- -- Reasonable conversion support -- ----------------------------------- function I_To_r (Arg: string(1 to FIO_d_WIDTH+1); Justified: side; Width: integer) return string is constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1); constant Sign: character := Arg(1); constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' '); variable IntWidth: integer range 0 to FIO_d_WIDTH; variable MsPos: integer range 1 to Value'length; variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks; begin if (Width = 0) or (Width > FIO_d_WIDTH+1) then IntWidth := FIO_d_WIDTH; else IntWidth := Width-1; end if; if (Justified = RIGHT) then return (Sign & Value(Value'length-IntWidth+1 to Value'length)); else for i in Value'range loop if Value(i) /= ' ' then MSPos := i; exit; end if; end loop; return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1)); end if; end I_To_r; ------------------------------------------- -- Reasonable output conversion function -- ------------------------------------------- function ReasonableOutput (Arg: string; Justified: side; Width: integer) return string is constant Argument: string(1 to Arg'length) := Arg; constant TypeSpec: string (1 to 2) := Argument(1 to 2); constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); begin case TypeSpec is when "U:" | "S:" | "V:" => return U_To_h(Value); when "I:" => return I_To_r(Value, Justified, Width); when "B:" | "L:" | "C:" => return Value; when others => return Argument; end case; end ReasonableOutput; ------------------------------------ -- Bit output conversion function -- ------------------------------------ function BitOutput (Arg: string; Justified: side; Width: integer) return string is constant Argument: string(1 to Arg'length) := Arg; constant TypeSpec: string (1 to 2) := Argument(1 to 2); constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); begin case TypeSpec is when "U:" | "S:" | "V:" => return (FIO_bv_PRE & Value & FIO_bv_POST); when "B:" => -- Value(1 to 1) instead of Value for LeapFrog return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST); when "I:" => return I_To_b(Value, Justified, Width); when "L:" => -- Value(1 to 1) instead of Value for LeapFrog return L_To_b(Value(1 to 1)); when others => return Argument; end case; end BitOutput; ------------------------------------------- -- Decimal output conversion function -- ------------------------------------------- function DecimalOutput (Arg: string) return integer is constant Argument: string(1 to Arg'length) := Arg; constant TypeSpec: string (1 to 2) := Argument(1 to 2); constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length); begin case TypeSpec is when "U:"| "V:" => return U_To_d(Value); when "S:" => return S_To_d(Value); when "I:" => return I_To_d(Value); when "B:" => return B_To_d(Value); when "L:" => return L_To_d(Value); when others => return integer'low; end case; end DecimalOutput; ---------------------------- -- Atomic print functions -- ---------------------------- function FIO_EOS (Format: in string; Pointer: in integer) return boolean is begin return (Pointer > Format'length); end FIO_EOS; -- Atomic value print function procedure FIO_PrintValue (F: out text; L: inout line; Format: in string; Pointer: inout integer; Last: in boolean := FALSE) is variable Char: character; begin while (not FIO_EOS(Format, Pointer)) loop Char := Format(Pointer); case Char is when '\' => Pointer := Pointer + 1; exit when (FIO_EOS(Format, Pointer)); Char := Format(Pointer); case Char is when 'n' => writeline(F, L); when others => write(L, Char); end case; when '%' => if Last then FIO_Warning_Fsbla(F, L, Format, Pointer); end if; Pointer := Pointer + 1; exit; when others => write(L, char); end case; Pointer := Pointer + 1; end loop; end FIO_PrintValue; ---- Atomic argument print function procedure FIO_PrintArg (F: out text; L: inout line; Format: in string; Pointer: inout integer; Arg: in string) is variable Char: character; variable Justified: side; variable Width: integer; begin FIO_PrintValue(F, L, Format, Pointer); Justified := RIGHT; Width := 0; while (not FIO_EOS(Format, Pointer)) loop Char := Format(Pointer); case Char is when '-' => Justified := LEFT; Pointer := Pointer + 1; when '0' to '9' => Width := Width*10 + C_DIGIT_CHARS_MAP(Char); Pointer := Pointer + 1; when 'r' => write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width); Pointer := Pointer + 1; exit; when 'b' => write(L, BitOutput(Arg, Justified, Width), Justified, Width); Pointer := Pointer + 1; exit; when 'd' => write(L, DecimalOutput(Arg), Justified, Width); Pointer := Pointer + 1; exit; when 'q' | 's' => write(L, Arg, Justified, Width); Pointer := Pointer + 1; exit; when others => FIO_Warning_Ufs(F, L, Format, Pointer, Char); write(L, Arg, Justified, Width); Pointer := Pointer + 1; exit; end case; end loop; end FIO_PrintArg; ----------------------------------------------------- -- The format string iteration expansion procedure -- ----------------------------------------------------- procedure FIO_FormatExpand (FMT: inout line; Format: in string; StartPointer: in positive) is variable Pointer: positive := StartPointer; variable TokenStart: positive; variable IterStringStart: positive; variable IterStringEnd: positive; variable IterCount: natural; variable OpenBrackets: natural; variable L: line; begin FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop case Format(Pointer) is -- look for format specifier when '%' => -- initialize iteration token search TokenStart := Pointer; IterCount := 0; Pointer := Pointer + 1; -- start iteration token search TOKEN_READ: while not FIO_EOS(Format, Pointer) loop case Format(Pointer) is -- read iteration counter when '0' to '9' => IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer)); Pointer := Pointer + 1; -- expect open bracket when '{' => -- initialize iteration string read OpenBrackets := 1; IterStringStart := Pointer + 1; Pointer := Pointer + 1; -- quit prematurely when iteration count is 0 next FORMAT_SEARCH when (IterCount = 0); -- start iteration string read ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop case Format(Pointer) is -- keep track of open brackets when '{' => OpenBrackets := OpenBrackets + 1; Pointer := Pointer + 1; -- when closing bracket is found, process iteration string when '}' => OpenBrackets := OpenBrackets - 1; if (OpenBrackets = 0) then IterStringEnd := Pointer-1; if (TokenStart /= 1) then write(L, Format(1 to TokenStart-1)); end if; for i in 1 to IterCount loop write(L, Format(IterStringStart to IterStringEnd)); end loop; if (IterStringEnd /= Format'length) then write(L, Format(IterStringEnd+2 to Format'length)); end if; -- call expansion procedure recursively on expanded format FIO_FormatExpand(FMT, L.all, TokenStart); deallocate(L); return; end if; Pointer := Pointer + 1; -- skip escaped characters when '\' => Pointer := Pointer + 2; -- read iteration string when others => Pointer := Pointer + 1; end case; end loop ITER_STRING_READ; -- stop iteration token search when no opening bracket found when others => Pointer := Pointer + 1; next FORMAT_SEARCH; end case; end loop TOKEN_READ; -- skip escaped characters when '\' => Pointer := Pointer + 2; -- read other characters when others => Pointer := Pointer + 1; end case; end loop FORMAT_SEARCH; write(FMT, Format); deallocate(L); end FIO_FormatExpand; -------------------------- -- The fprint procedure -- -------------------------- procedure fprint (F: out text; L: inout line; Format: in string; A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL; A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL; A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL; A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL ) is variable Pointer: integer; variable FMT: line; begin Pointer := 1; FIO_FormatExpand (FMT, Format, Format'low); if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 ); if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 ); if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 ); if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 ); if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 ); if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 ); if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 ); if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 ); if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 ); if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10); if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11); if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12); if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13); if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14); if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15); if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16); if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17); if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18); if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19); if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20); if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21); if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22); if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23); if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24); if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25); if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26); if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27); if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28); if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29); if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30); if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31); if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32); end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; end if; FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE); deallocate(FMT); end fprint; ------------------------------------------- -- Formatted output conversion functions -- ------------------------------------------- function fo (Arg: unsigned) return string is constant Argument: unsigned(1 to Arg'length) := Arg; variable Result: string(1 to Arg'length); begin for i in Argument'range loop Result(i) := C_STD_LOGIC_MAP(Argument(i)); end loop; return ("U:" & Result); end fo; function fo (Arg: signed) return string is constant Argument: signed(1 to Arg'length) := Arg; variable Result: string(1 to Arg'length); begin for i in Argument'range loop Result(i) := C_STD_LOGIC_MAP(Argument(i)); end loop; return ("S:" & Result); end fo; function fo (Arg: std_logic_vector) return string is constant Argument: std_logic_vector(1 to Arg'length) := Arg; variable Result: string(1 to Arg'length); begin for i in Argument'range loop Result(i) := C_STD_LOGIC_MAP(Argument(i)); end loop; return ("V:" & Result); end fo; function fo (Arg: std_ulogic_vector) return string is constant Argument: std_ulogic_vector(1 to Arg'length) := Arg; variable Result: string(1 to Arg'length); begin for i in Argument'range loop Result(i) := C_STD_LOGIC_MAP(Argument(i)); end loop; return ("V:" & Result); end fo; function fo (Arg: bit_vector) return string is constant Argument: bit_vector(1 to Arg'length) := Arg; variable Result: string(1 to Arg'length); begin for i in Argument'range loop Result(i) := C_BIT_MAP(Argument(i)); end loop; return ("V:" & Result); end fo; function fo (Arg: integer) return string is variable Argument: integer := Arg; variable Result: string(1 to FIO_d_WIDTH) := (others => ' '); variable Sign: character := ' '; begin if (Argument < 0) and (Argument /= integer'low) then Sign := '-'; Argument := -Argument; end if; for i in Result'reverse_range loop Result(i) := C_DIGITS_MAP(Argument mod 10); Argument := Argument / 10; exit when (Argument = 0); end loop; return ("I:" & Sign & Result); end fo; function fo (Arg: std_ulogic) return string is begin return ("B:" & C_STD_LOGIC_MAP(Arg)); end fo; function fo (Arg: bit) return string is begin return ("B:" & C_BIT_MAP(Arg)); end fo; function fo (Arg: boolean) return string is begin if (ARG = TRUE) then return ("L:T"); else return ("L:F"); end if; end fo; function fo (Arg: character) return string is begin return ("C:" & Arg); end fo; function fo (Arg: string) return string is begin return Arg; end fo; function fo (Arg: time) return string is begin return fo (integer (Arg / 1 ns)); end fo; end PCK_FIO;