-- stringPack -- Funktionen fuer die formatierte Textausgabe -- -- 17.01.2009 G. Kemnitz library ieee; use ieee.std_logic_1164.all; use std.textio.all; package stringPack is --------------- Operatorfunktionen -------------------------------- -- := / -- zur formatierten Umwandlung von Datenobjekten in Zeichenketten ------------------------------------------------------------------- -- Format := [fmtc][n][.m][Basis][lr][unit] -- fmtc: Art der Zahlendarstellung (character) -- 'b' -- als Bitvektor im Zweierkomplement -- 'o' -- oktal -- 'h' -- hexadezimal -- 'i' -- als vorzeichenbehaftete Dezimalzahl -- 'u' -- als positive Zahl -- 'f' -- als Gleitkommazahl -- n: Zeichenkettenlaenge (Mindest- und Richtwert, positive) -- m: Anzahl der Nachkommastellen (natural) -- Basis: Basis des Zahlensystems (positive, max. 16) -- lr: Ausrichtung ('l' -- links; 'r' -- rechts) -- unit: Masseinheit fuer Zeitangaben ("fs", "ps", ..., string) function "/"(a: character; fmt: string) return string; function "/"(a: string; fmt: string) return string; function "/"(a: bit; fmt: string) return string; function "/"(a: std_ulogic; fmt: string) return string; function "/"(a: boolean; fmt: string) return string; function "/"(a: integer; fmt: string) return string; function "/"(a: real; fmt: string) return string; function "/"(a: time; fmt: string) return string; function "/"(a: bit_vector; fmt: string) return string; function "/"(a: std_logic_vector; fmt: string) return string; function "/"(a: std_ulogic_vector; fmt: string) return string; ---------- Konkationation zur Zeichenketten function "&"(a: string; b: integer) return string; function "&"(a: integer; b: string) return string; function "&"(a: string; b: time) return string; function "&"(a: time; b: string) return string; function "&"(a: string; b: real) return string; function "&"(a: real; b: string) return string; function "&"(a: string; b: bit) return string; function "&"(a: bit; b: string) return string; function "&"(a: string; b: boolean) return string; function "&"(a: boolean; b: string) return string; function "&"(a: string; b: std_ulogic) return string; function "&"(a: std_ulogic; b: string) return string; ---------- Konvertierfunktionen in Zeichenketten ------------ -- := str(, [Format-Angaben]) -- -- maximale Ziffernanzahl einer ganzen Zahl: constant maxZiffernAnz: positive:=20; function str(a: character) return string; function str(a: bit) return string; function str(a: std_ulogic) return string; function str(a: boolean) return string; function str(bv: bit_vector) return string; function str(bv: std_ulogic_vector) return string; function str(bv: std_logic_vector) return string; function str(a: integer; Basis: character:='d') return string; function str(a: real; m: natural:=2; Basis: character:='d') return string; function str(a: time; m: natural:=2; unit: string(1 to 2):="ns"; Basis: character:='d') return string; -- Ausgabe einer Zeichenkette auf der Standardausgabe procedure write(a: string); end package; package body stringPack is --------------------------------------------------------------- -- Hilfsfuntionen fuer str(...) -- Konvertierfunktionen in Zeichen ---- bit constant bit2str_Tab: string:="01"; function char(a: bit) return character is begin return bit2str_Tab(bit'pos(a)+1); end function; ---- std_ulogic constant ulogic2str_Tab: string:="UX01ZWLH-"; function char(a: std_ulogic) return character is begin return ulogic2str_Tab(std_ulogic'pos(a)+1); end function; ----------------------------------------------------------------- ---------- Konvertierfunktionen in Zeichenketten ------------ -- := str(, [Format-Angaben]) ---- character function str(a: character) return string is constant s: string(1 to 1):=(1=>a); begin return s; end function; ---- bit function str(a: bit) return string is begin return str(bit2str_Tab(bit'pos(a)+1)); end function; ---- std_ulogic function str(a: std_ulogic) return string is begin return str(ulogic2str_Tab(std_ulogic'pos(a)+1)); end function; ---- boolean function str(a: boolean) return string is begin return boolean'image(a); end function; ---- bit_vector function str(bv: bit_vector) return string is variable s: string(1 to bv'length); variable idx: positive:=1; begin for id in bv'range loop s(idx):=char(bv(id)); idx:=idx+1; end loop; return s; end function; ---- std_ulogic_vector function str(bv: std_ulogic_vector) return string is variable s: string(1 to bv'length); variable idx: positive:=1; begin for id in bv'range loop s(idx):=char(bv(id)); idx:=idx+1; end loop; return s; end function; ---- std_logic_vector function str(bv: std_logic_vector) return string is variable s: string(1 to bv'length); variable idx: positive:=1; begin for id in bv'range loop s(idx):=char(bv(id)); idx:=idx+1; end loop; return s; end function; ---- integer function str(a: integer; Basis: character:='d') return string is begin return str(real(a), 0, Basis); end function; ---- real constant digit2str_Tab: string:="0123456789abcdef"; function str(a: real; m: natural:=2; Basis: character:='d') return string is constant n: positive:=maxZiffernAnz; variable s: string(n downto 1); variable idx: positive:=1; variable betrag: integer; variable sign: boolean:=false; variable b: positive; variable digit: integer; variable ZNr: integer:=-m; begin case Basis is when 'b' => b:=2; s(1):='b'; idx:=2; when 'o' => b:=8; s(1):='o'; idx:=2; when 'h' => b:=16; s(1):='h'; idx:=2; when others => b:=10; end case; betrag := integer(a*real(b**m)); if betrag < 0 then betrag := -betrag; sign:=True; end if; while idx<=n and betrag>0 loop digit:= betrag mod b; s(idx):= digit2str_Tab(digit+1); idx := idx+1; betrag:=betrag/b; ZNr:=ZNr+1; if ZNr=0 then s(idx):= '.'; idx := idx+1; end if; end loop; if sign and idx<=n then s(idx):= '-'; idx := idx+1; elsif sign and idx>n then s(n downto n-1):="-?"; elsif idx>n and Betrag>0 then s(n):='?'; end if; return s(idx-1 downto 1); end function; ---- time function str(a: time; m: natural:=2; unit: string(1 to 2):="ns"; Basis: character:='d') return string is variable f: real:=real(a/(1 fs)); begin case unit is when "fs" => return str(a/fs, Basis) & " fs"; when "ps" => return str(f/1.0E3, m, Basis) & " ps"; when "us" => return str(f/1.0E9, m, Basis) & " us"; when "ms" => return str(f/1.0E12, m, Basis) & " ms"; when "se" => return str(f/1.0E15, m, Basis) & " sec"; when "mi" => return str(f/6.0E16, m, Basis) & " min"; when "hr" => return str(f/3.6E18, m, Basis) & " hr"; when others => return str(f/1.0E6, m, Basis) & " ns"; end case; end function; --------------------------------------------------------- -- Hilfsfunktionen fuer die Operatorfunktionen -- Test, ob Bitzeichenkette function is_BitString(s: string) return boolean is begin for idx in s'range loop if not (s(idx)='0' or s(idx)='1') then return false; end if; end loop; return true; end function; -- Umwandlung von Bitzeichenketten in eine positive Zahlen function uint(s: string) return natural is variable v: natural:=0; begin for idx in s'range loop v:=2*v; if s(idx)='1' then v:=v+1; end if; end loop; return v; end function; -- Umwandlung von Bitzeichenketten in eine vorzeichenbehaftete Zahlen function int(s: string) return integer is variable v: integer:=0; begin for idx in s'range loop v:=2*v; if s(idx)='1'then if idx=1 then v:=-1; else v:=v+1; end if; end if; end loop; return v; end function; -- Test, ob Formatbuchstabe constant fmtc_tab: string:="bodhiuf"; function is_fmtc(c: character) return boolean is begin for idx in fmtc_tab'range loop if fmtc_tab(idx)=c then return true; end if; end loop; return false; end function; -- Zeichen in Wert umrechnen procedure digitVal(Zeichen: character; Wert: out natural; ok: out boolean) is begin case Zeichen is when '0' => Wert:=0; ok:=true; when '1' => Wert:=1; ok:=true; when '2' => Wert:=2; ok:=true; when '3' => Wert:=3; ok:=true; when '4' => Wert:=4; ok:=true; when '5' => Wert:=5; ok:=true; when '6' => Wert:=6; ok:=true; when '7' => Wert:=7; ok:=true; when '8' => Wert:=8; ok:=true; when '9' => Wert:=9; ok:=true; when 'a'|'A' => Wert:=10; ok:=true; when 'b'|'B' => Wert:=11; ok:=true; when 'c'|'C' => Wert:=12; ok:=true; when 'd'|'D' => Wert:=13; ok:=true; when 'e'|'E' => Wert:=14; ok:=true; when 'f'|'F' => Wert:=15; ok:=true; when others => Wert:= 0; ok:=false; end case; end procedure; -- Zeichenfolge ab Position idx in einen Wert umrechnen procedure getWert(s: string; idx: inout positive; a: out natural) is variable vs: string(1 to s'length):=s; variable v, w: natural:=0; variable ok: boolean; begin while idx <= vs'length loop digitVal(vs(idx), v, ok); exit when not ok; w := W*10 + v; idx := idx+1; end loop; a:=w; end procedure; -- Formatstring in seine Bestandteile zerlegen procedure getFormat(fmt: in string; fmtc: out character; -- Formatierungstyp n: out natural; -- Gesamtzeichenanzahl m: out natural; -- Anzahl der Nachkommastellen (real, time) lr: out character; -- Ausrichtung (r-rechts, l-links) unit: out string(1 to 2) -- Masseinheit (time) ) is variable s: string(1 to fmt'length):=fmt; variable idx: positive:=1; begin if s'length>0 and is_fmtc(s(1)) then -- bei Begin mit Formatbuchstaben fmtc:=s(1); idx:=2; else fmtc:='s'; end if; getWert(s, idx, n); -- Gesamtzeichenanzahl lesen if s'length>idx and s(idx)='.' then -- wenn '.' folgt, Anzahl der idx:=idx+1; getWert(s, idx, m); -- Nachkommastellen lesen else m:=0; end if; if (s'length>=idx) and ((s(idx)='l') or (s(idx)='r')) then lr:=s(idx); -- Zeichen für die Ausrichtung lesen idx:=idx+1; else lr:='r'; end if; if s'length>idx then -- Zeichen für die Masseinheit lesen unit:=s(idx to idx+1); else unit:="ns"; end if; end procedure; -- Zeichenkette ausrichten function align(a: string; n: positive; lr: character) return string is variable c: string(1 to n):=(others=>' '); begin if a'length >= n then return a; elsif a'length>0 then if lr='l' then c(1 to a'length):=a; else c(n-a'length+1 to n):=a; end if; end if; return c; end function; -- Formatierung einer Bitvektor-Zeichenkette function str(s: string; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("Formt BV: fmtc="& str(fmtc)&" n="&str(n)&" lr="&str(lr)); if is_bitstring(s) then case fmtc is when 'i'|'d' => return align(str(int(s), fmtc), n, lr); when 'u'|'b'|'o'|'h' => return align(str(uint(s), fmtc), n, lr); when others => return align(s, n, lr); end case; else return align(s, n, lr); end if; end function; --------------- Operatorfunktionen -------------------------------- -- Zeichenkette := / ---- character function "/"(a: character; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("char/fmt: fmtc="& str(fmtc)&" n="&str(n)&" lr="&str(lr)); return align(str(a), n, lr); end function; ---- string function "/"(a: string; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("string/fmt: fmtc="& str(fmtc)&" n="&str(n)&" lr="&str(lr)); return align(a, n, lr); end function; ---- bit function "/"(a: bit; fmt: string) return string is begin return char(a)/fmt; end function; ---- std_ulogic function "/"(a: std_ulogic; fmt: string) return string is begin return char(a)/fmt; end function; ---- boolean function "/"(a: boolean; fmt: string) return string is begin return str(a)/fmt; end function; ---- integer function "/"(a: integer; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("integer/fmt: fmtc="& str(fmtc)&" n="&str(n)&" lr="&str(lr)); return align(str(a, fmtc), n, lr); end function; ---- real function "/"(a: real; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("real/fmt: fmtc="& str(fmtc)&" n="&str(n)&" lr="&str(lr)); return align(str(a, m, fmtc), n, lr); end function; ---- time function "/"(a: time; fmt: string) return string is variable fmtc, lr: character; variable n, m: natural; variable unit: string(1 to 2); begin getFormat(fmt, fmtc, n, m, lr, unit); --write("char/fmt: fmtc="& str(fmtc)&" n="&str(n)&" m="&m&" lr="&str(lr)&" unit="&unit); return align(str(a, m, unit, fmtc), n, lr); end function; ---- bit_vector function "/"(a: bit_vector; fmt: string) return string is begin --write(str(a)&" / <"&fmt&">"); return str(str(a), fmt); end function; --- std_logic_vector function "/"(a: std_logic_vector; fmt: string) return string is begin return str(str(a), fmt); end function; --- std_ulogic_vector function "/"(a: std_ulogic_vector; fmt: string) return string is begin return str(str(a), fmt); end function; ---------- Konkationation zur Zeichenketten ------------------------ function "&"(a: string; b: integer) return string is begin return a & str(b); end function; function "&"(a: integer; b: string) return string is begin return str(a) & b; end function; function "&"(a: string; b: time) return string is begin return a & str(b); end function; function "&"(a: time; b: string) return string is begin return str(a) & b; end function; function "&"(a: string; b: real) return string is begin return a & str(b); end function; function "&"(a: real; b: string) return string is begin return str(a) & b; end function; function "&"(a: string; b: bit) return string is begin return a & str(b); end function; function "&"(a: bit; b: string) return string is begin return str(a) & b; end function; function "&"(a: string; b: boolean) return string is begin return a & str(b); end function; function "&"(a: boolean; b: string) return string is begin return str(a) & b; end function; function "&"(a: string; b: std_ulogic) return string is begin return a & str(b); end function; function "&"(a: std_ulogic; b: string) return string is begin return str(a) & b; end function; ----------------------------------------------------- procedure write(a: string) is begin write(output, a); end procedure; end package body;