URL
https://opencores.org/ocsvn/ahbmaster/ahbmaster/trunk
Subversion Repositories ahbmaster
[/] [ahbmaster/] [trunk/] [test79_AHBmaster/] [component/] [work/] [top/] [CoreUARTapb_0/] [rtl/] [vhdl/] [amba_bfm/] [textio.vhd] - Rev 3
Compare with Previous | Blame | View Log
-- ********************************************************************/ -- Actel Corporation Proprietary and Confidential -- Copyright 2008 Actel Corporation. All rights reserved. -- -- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN -- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED -- IN ADVANCE IN WRITING. -- -- Description: AMBA BFMs -- AHB Lite BFM -- -- Revision Information: -- Date Description -- 01Sep07 Initial Release -- 14Sep07 Updated for 1.2 functionality -- 25Sep07 Updated for 1.3 functionality -- 09Nov07 Updated for 1.4 functionality -- 08May08 2.0 for Soft IP Usage -- -- -- SVN Revision Information: -- SVN $Revision: 2437 $ -- SVN $Date: 2008-09-18 03:33:46 -0700 (Thu, 18 Sep 2008) $ -- -- -- Resolved SARs -- SAR Date Who Description -- -- -- Notes: -- -- *********************************************************************/ -- *********************************************************************/ -- Copyright 2005 Actel Corporation. All rights reserved. -- IP Solutions Group -- -- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN -- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED -- IN ADVANCE IN WRITING. -- -- File : textio.vhd -- -- Originator : I Bryant -- -- Date : 22 Jan 1997 -- -- Description : Implements Basic Printing Routines for the Test harness -- -- Revision History: -- 3.02 08Jan99 IPB : Nokia Modifications -- 2.0 01Jun01 IPB : VariCore Production Code Release 1 -- 2.1 11Mar02 IPB : Added %t support -- Revision history for version in the Core1553 Cores -- Rev: 1.0 01Apr02 IPB : Initial Code (Copied from PCI Cores) -- Rev: 1.1 09Jul02 IPB : First Cut EAP -- Rev: 1.2 01Aug02 IPB : Second EAP -- Rev: 2.0 22Aug02 IPB : Production -- Rev: 2.1 22Oct03 IPB : Updated to use IEEE.NUMERIC and 1076-93 -- Rev: 2.2 10Mar04 IPB : Added sprintf functions and %c support -- BRM Release -- Rev: 1.0 01May04 IPB : Pre Production -- Rev: 2.0 27May04 IPB : First Production Release -- Rev: 2.1 24Jan05 IPB : PA3/E Production Release -- -- CoreABC Release -- Rev: 1.1 08May06 IPB : EAP Release -- -- CoreConsolisation AMBA Project -- Rev: 3.1 07Jan07 IPB : CoreConsole Release - Fixed negative number handling in %u on 32 bit values -- -- AMBA BFM -- Rev: 1.0 18Jul07 IPB : -- Rev: 1.1 24Aug07 IPB : See users guide 1.0 for changes -- Rev: 1.2 14Sep07 IPB : See users guide 1.2 for changes -- -- Notes : -- Supported Formats -- %d decimal -- %h hexadecimal Integer or known vector -- %x hexadecimal Integer or vector with X's -- %u hexadecimal Integer or vector unsigned hex value -- %b binary -- %s string -- %t prints time in ns -- -- Also Supports %6 i.e Width Field -- %0 Fill with Zeros -- --------------------------------------------------------------------------- library std; use std.textio.all; use work.bfm_misc.all; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --------------------------------------------------------------------------- -- Declarations etc -- package bfm_textio is constant MAXSTRLEN : INTEGER := 256; type T_NUMTYPE is ( NONE, INT, VECT, STRG); type T_FMT is record f_type : T_NUMTYPE; f_integer : INTEGER; f_vector : QWORD; f_length : INTEGER; f_string : STRING (1 to MAXSTRLEN); end record; type T_FMT_ARRAY is array ( integer range <> ) of T_FMT; function is01 ( v: std_logic) return BOOLEAN; function is01 ( v: unsigned; len : INTEGER) return BOOLEAN; function strlen( str: STRING) return INTEGER; function strcopy ( instr : STRING) return STRING; procedure printf( str : STRING; params : T_FMT_ARRAY); procedure printf( str : STRING; params : T_FMT); procedure printf( str : STRING ); procedure sprintf( strout : out STRING; str : STRING; params : T_FMT_ARRAY); procedure sprintf( strout : out STRING; str : STRING; params : T_FMT); procedure sprintf( strout : out STRING; str : STRING ); procedure ifprintf( enable : BOOLEAN; str : STRING; params : T_FMT_ARRAY); procedure ifprintf( enable : BOOLEAN; str : STRING; params : T_FMT); procedure ifprintf( enable : BOOLEAN; str : STRING ); function fmt ( x : INTEGER) return T_FMT; function fmt ( x : std_logic_vector) return T_FMT; function fmt ( x : unsigned) return T_FMT; function fmt ( x : string ) return T_FMT; function fmt ( x : character ) return T_FMT; function fmt ( x : boolean ) return T_FMT; function fmt ( x : std_logic) return T_FMT; function inttostr( value : INTEGER; base : INTEGER; numlen : INTEGER :=0; zeros: BOOLEAN:=FALSE) return STRING; function inrange ( x, l: integer) return integer; end bfm_textio; --------------------------------------------------------------------------- -- The Body -- package body bfm_textio is function inrange ( x, l: integer) return integer is begin if x<=l then return(x); else return(l); end if; end inrange; --------------------------------------------------------------------------- -- Basic Character Converters -- function to_char( x : INTEGER range 0 to 15) return character is begin case x is when 0 => return('0'); when 1 => return('1'); when 2 => return('2'); when 3 => return('3'); when 4 => return('4'); when 5 => return('5'); when 6 => return('6'); when 7 => return('7'); when 8 => return('8'); when 9 => return('9'); when 10 => return('A'); when 11 => return('B'); when 12 => return('C'); when 13 => return('D'); when 14 => return('E'); when 15 => return('F'); end case; end to_char; function to_char( v : std_logic ) return CHARACTER is begin case v is when '0' => return('0'); when '1' => return('1'); when 'L' => return('L'); when 'H' => return('H'); when 'Z' => return('Z'); when 'X' => return('X'); when 'U' => return('U'); when '-' => return('-'); when 'W' => return('W'); end case; end to_char; --------------------------------------------------------------------------- -- special std_logic_vector handling -- function is01 ( v: std_logic) return BOOLEAN is begin return ( v='0' or v='1'); end is01; function is01 ( v: UNSIGNED ; len : INTEGER) return BOOLEAN is variable ok : BOOLEAN; begin ok := TRUE; for i in 0 to len-1 loop ok := ok and is01( v(i)); end loop; return (ok); end is01; --------------------------------------------------------------------------- -- special integer to unsigned -- function to_unsigned_32 ( x : integer ) return UNSIGNED is variable x1 : UNSIGNED(31 downto 0); variable xi : integer; begin -- Note this causes an integer overflow on VSS and QuickVHDL -- Cannout handle -ve numbers -- x1 := conv_std_logic_vector( x,32); if x < 0 then xi := x + 2 ** 30 + 2 ** 30; x1(30 downto 0) := to_unsigned( xi, 31); x1(31) := '1'; else x1(30 downto 0) := to_unsigned( x, 31); x1(31) := '0'; end if; return(x1); end to_unsigned_32; --------------------------------------------------------------------------- -- String Functions -- function strlen( str: STRING) return INTEGER is variable i: INTEGER; begin i:=1; while i<= MAXSTRLEN and str(i)/=NUL loop i:=i+1; end loop; return(i-1); end strlen; function strcopy ( instr : STRING) return STRING is variable outstr : STRING (1 to MAXSTRLEN); variable i: INTEGER; begin outstr(1 to instr'length) := instr; outstr(instr'length+1) := NUL; return(outstr); end strcopy; --------------------------------------------------------------------------- -- Number Printing Routines -- function hexchar ( vect : UNSIGNED) return character is variable v : UNSIGNED ( 3 downto 0); variable char : CHARACTER; begin v := vect; if is01(v(0)) and is01(v(1)) and is01(v(2)) and is01(v(3)) then char := to_char (to_integer(v)); elsif v(0)=v(1) and v(0)=v(2) and v(0)=v(3) then char:= to_char(v(0)); else char:='?'; end if; return(char); end hexchar; function inttostr( value : INTEGER; base : INTEGER; numlen : INTEGER :=0; zeros: BOOLEAN:=FALSE) return STRING is variable str : STRING (1 to MAXSTRLEN); variable s1 : STRING (MAXSTRLEN downto 1); variable pos,x,xn,x1 : INTEGER; begin if value=-2147483648 then -- str(1 to 9) := "UNDERFLOW"; -- str(10) := NUL; str(1 to 11) := "-2147483648"; -- print actual value anyway str(12) := NUL; else x := abs(value); pos := 0; while x>0 or pos=0 loop pos:=pos+1; xn := x / base; x1 := x - xn * base ; x := xn; s1(pos) := to_char(x1); end loop; if value<0 then pos:=pos+1; s1(pos):='-'; end if; if pos>numlen then str(1 to pos) := s1 (pos downto 1); str(pos+1) := NUL; else case ZEROS is when TRUE => str := (others => '0'); when FALSE => str := (others => ' '); end case; str( (1+numlen-pos) to numlen) := s1(pos downto 1); str(numlen+1) := NUL; end if; end if; return(str); end inttostr; function vecttostr( value : UNSIGNED; len : INTEGER; base : INTEGER; numlen : INTEGER :=0; zeros: BOOLEAN:=FALSE) return STRING is variable str : STRING (1 to MAXSTRLEN); variable s1 : STRING (MAXSTRLEN downto 1); variable pos, len4 : INTEGER; variable x : QWORD; variable vect4 : UNSIGNED(3 downto 0); begin x:=value; if len<64 then x(63 downto len) := (others =>'0'); end if; case base is when 2 => for i in 0 to len-1 loop s1(i+1) := to_char(value(i)); end loop; pos:=len; when 16 => len4 := ((len+3)/4); for i in 0 to len4-1 loop vect4 := x( 3+(4*i) downto 4*i); s1(i+1) := hexchar(vect4); end loop; pos:=len4; when others => s1:=strcopy("ESAB LAGELLI"); end case; if pos>numlen then str(1 to pos) := s1 (pos downto 1); str(pos+1) := NUL; else case ZEROS is when TRUE => str := (others => '0'); when FALSE => str := (others => ' '); end case; str( (1+numlen-pos) to numlen) := s1(pos downto 1); str(numlen+1) := NUL; end if; return(str); end vecttostr; --------------------------------------------------------------------------- -- Multi Type input handlers -- function fmt ( x : BOOLEAN) return T_FMT is variable fm : T_FMT; begin fm.f_type := INT; if x then fm.f_integer := 1; else fm.f_integer := 0; end if; return(fm); end fmt; function fmt ( x : INTEGER) return T_FMT is variable fm : T_FMT; begin fm.f_type := INT; fm.f_integer := x; return(fm); end fmt; function fmt ( x : UNSIGNED) return T_FMT is variable fm : T_FMT; begin fm.f_type := VECT; fm.f_vector(x'length-1 downto 0) := x; fm.f_length := x'length; return(fm); end fmt; function fmt ( x : std_logic_vector) return T_FMT is variable fm : T_FMT; begin fm.f_type := VECT; fm.f_vector(x'length-1 downto 0) := to_unsigned(x); fm.f_length := x'length; return(fm); end fmt; function fmt ( x : string ) return T_FMT is variable fm : T_FMT; begin fm.f_type := STRG; fm.f_string(x'range) := x; if x'length+1<MAXSTRLEN then fm.f_string(x'length+1) := NUL; end if; fm.f_length := x'length; return(fm); end fmt; function fmt ( x : character ) return T_FMT is variable fm : T_FMT; begin fm.f_type := STRG; fm.f_string(1) := x; fm.f_string(2) := NUL; fm.f_length := 1; return(fm); end fmt; function fmt ( x : std_logic) return T_FMT is variable fm : T_FMT; variable x1 : UNSIGNED ( 0 downto 0); begin x1(0) := x; fm.f_type := VECT; fm.f_vector(x1'length-1 downto 0) := x1; fm.f_length := x1'length; return(fm); end fmt; --------------------------------------------------------------------------- -- The Main Print Routine -- procedure theprintf( SPRINTF : BOOLEAN; strout : out string; str : STRING; Params : T_FMT_ARRAY ) is variable ll : LINE; variable str1,pstr : STRING (1 to MAXSTRLEN); variable ip,op,pp,iplen : INTEGER; variable numlen : INTEGER; variable zeros : BOOLEAN; variable more : BOOLEAN; variable intval : INTEGER; variable vectval: QWORD; variable len : INTEGER; variable ftype : T_NUMTYPE; variable tnow : INTEGER; begin iplen := str'length; ip:=1; op:=0; pp:=params'low; while ip<=iplen and str( inrange(ip,iplen))/=NUL loop if str(ip) = '%' then more:=TRUE; numlen:=0; zeros:=FALSE; while more loop more:=FALSE; ip:=ip+1; if str(ip)/='t' then -- 17Jul07 %t has no parameters, errors if last parameter! ftype := params(pp).f_type; intval := params(pp).f_integer; vectval:= params(pp).f_vector; len := params(pp).f_length; end if; case str(ip) is when '0' => ZEROS:=TRUE; more:=TRUE; when '1' to '9' => numlen:= 10* numlen + character'pos(str(ip))-48; more := TRUE; when '%' => pstr := strcopy("%"); when 'd' => case ftype is when INT => pstr := inttostr(intval,10,numlen,zeros); when VECT => if is01(vectval,len) then intval:= to_integer(vectval(len-1 downto 0)); pstr := inttostr(intval,10,numlen,zeros); end if; when others => pstr := strcopy("INVALID PRINTF d:" & str); end case; pp:=pp+1; when 't' => tnow := NOW / 1 ns; pstr := inttostr(tnow,10,numlen,zeros); when 'h' => case ftype is when INT => pstr := inttostr(intval,16,numlen,zeros); when VECT => if is01(vectval,len) then intval:= to_integer(vectval(len-1 downto 0)); pstr := inttostr(intval,16,numlen,zeros); end if; when others => pstr := strcopy("INVALID PRINTF h:" & str); end case; pp:=pp+1; when 'u' => case ftype is when INT => vectval := ( others => '0'); vectval(31 downto 0) := to_unsigned_32(intval); len:=32; pstr := vecttostr(vectval,len,16,numlen,zeros); when VECT => pstr := vecttostr(vectval,len,16,numlen,zeros); when others => pstr := strcopy("INVALID PRINTF h:" & str); end case; pp:=pp+1; when 'b' => case ftype is when INT => vectval := ( others => '0'); vectval(31 downto 0) := to_unsigned(intval,32); len:=1; for i in 1 to 31 loop if vectval(i)='1' then len:=i; end if; end loop; pstr := vecttostr(vectval,len,2,numlen,zeros); when VECT => pstr := vecttostr(vectval,len,2,numlen,zeros); when others => pstr := strcopy("INVALID PRINTF b:" & str); end case; pp:=pp+1; when 'x' => case ftype is -- when INT => pstr := inttostr(intval,16,numlen,zeros); --28nov07 to sort out -ve nos when INT => vectval := ( others => '0'); vectval(31 downto 0) := to_unsigned_32(intval); len:=32; pstr := vecttostr(vectval,len,16,numlen,zeros); when VECT => pstr := vecttostr(vectval,len,16,numlen,zeros); when others => pstr := strcopy("INVALID PRINTF x:" & str); end case; pp:=pp+1; when 's' => case ftype is when STRG => pstr :=params(pp).f_string; when others => pstr := strcopy("INVALID PRINTF s:" & str); end case; pp:=pp+1; when 'c' => case ftype is when STRG => pstr :=params(pp).f_string; when others => pstr := strcopy("INVALID PRINTF s:" & str); end case; pp:=pp+1; when others => pstr := strcopy("ILLEGAL FORMAT"); assert FALSE report "TEXTIO Processing Problem" severity FAILURE; end case; end loop; len := strlen(pstr); for i in 1 to len loop str1(op+i) := pstr(i); end loop; ip:=ip+1; op:=op+len; elsif str(ip)='\' then case str(ip+1) is when 'n' => str1(op+1):= NUL; if not SPRINTF then write( ll , str1 ); writeline( output, ll); end if; op := 0; ip:=ip+1; str1(op+1) := NUL; when others => end case; ip:=ip+1; else op:=op+1; str1(op) := str(ip); ip:=ip+1; end if; end loop; if op>0 then str1(op+1):=NUL; if SPRINTF then strout := str1(strout'range); else write( ll , str1 ); writeline(output, ll); end if; end if; end theprintf; ------------------------------------------------------------------------------------- procedure printf( str : STRING; params : T_FMT ) is variable strout : STRING (1 to MAXSTRLEN); variable f_fmt : T_FMT_ARRAY ( 1 to 1); begin f_fmt(1) := params; theprintf(FALSE,strout,str,f_fmt); end printf; procedure printf( str : STRING ) is variable strout : STRING (1 to MAXSTRLEN); variable fm : T_FMT_ARRAY ( 1 to 1); begin fm(1).f_type := NONE; theprintf(FALSE,strout,str,fm); end printf; procedure printf( str : STRING; Params : T_FMT_ARRAY ) is variable strout : STRING (1 to MAXSTRLEN); begin theprintf(FALSE,strout,str,Params); end printf; ------------------------------------------------------------------------------------- procedure sprintf( strout : out STRING; str : STRING; Params : T_FMT_ARRAY ) is begin theprintf( TRUE, strout, str,Params); end sprintf; procedure sprintf( strout : out STRING; str : STRING; params : T_FMT ) is variable f_fmt : T_FMT_ARRAY ( 1 to 1); begin f_fmt(1) := params; theprintf( TRUE,strout,str,f_fmt); end sprintf; procedure sprintf( strout : out STRING; str : STRING ) is variable fm : T_FMT_ARRAY ( 1 to 1); begin fm(1).f_type := NONE; theprintf( TRUE,strout,str,fm); end sprintf; ------------------------------------------------------------------------------------- procedure ifprintf( enable : BOOLEAN; str : STRING; Params : T_FMT_ARRAY ) is begin if enable then printf(str,params); end if; end ifprintf; procedure ifprintf( enable : BOOLEAN; str : STRING; params : T_FMT ) is variable f_fmt : T_FMT_ARRAY ( 1 to 1); begin if enable then f_fmt(1) := params; printf(str,f_fmt); end if; end ifprintf; procedure ifprintf( enable : BOOLEAN; str : STRING ) is variable fm : T_FMT_ARRAY ( 1 to 1); begin if enable then fm(1).f_type := NONE; printf(str,fm); end if; end ifprintf; end bfm_textio; --------------------------------------------------------------------------- -- This a Test For the above Routines -- library IEEE; use ieee.std_logic_1164.all; use IEEE.std_logic_arith.all; use std.textio.all; use work.bfm_textio.all; entity bfm_textio_test is end bfm_textio_test; architecture TB of bfm_textio_test is begin process variable dw : std_logic_vector ( 9 downto 0); variable xx : std_logic_vector(15 downto 0); variable ll : LINE; file FSTR : text open write_mode is "Cpulog.txt" ; variable strout : STRING(1 to 80); variable intval : integer; begin wait for 1 ns ; printf("Textio Test strings v1.2"); printf("Note I think MTI uses variable width Fonts"); xx:= conv_std_logic_vector( 16#AAAA#,16); printf("Using 04x %04x",fmt(xx)); printf("Using 04u %04u",fmt(xx)); printf("-d...123456 = %d",fmt(123456)); printf("-8d..123456 = %8d",fmt(123456)); printf("-08d.123456 = %08d",fmt(123456)); printf("-02d.123456 = %02d",fmt(123456)); printf("This is a Binary %016b",fmt(16#55AA#)); printf("This is a Decimal %d",fmt(1234)); printf("This is a Hex %h",fmt(16#1234#)); printf("This is a Simple String"); printf("This is a Simple String with a CRLF\nin the middle"); printf("Read Location %d = %h",fmt(123456)&fmt(16#654321#)); printf("-d...-123456 = %d",fmt(-123456)); printf("-d...-123456 = %08d",fmt(-123456)); dw := ( others => '0'); printf("-x...000 = %x",fmt(dw)); dw := "0101010101"; printf("-x...155 = %x",fmt(dw)); printf("-b...155 = %b",fmt(dw)); dw := "0101U10101"; printf("-x...1?5 = %x",fmt(dw)); printf("-b...1?5 = %b",fmt(dw)); dw := "01UUUU0101"; printf("-x...1U5 = %x",fmt(dw)); printf("-b...1U5 = %b",fmt(dw)); printf(" Time is %t ns "); printf("Negative handling"); intval := 16#0C00000#; -- set this line to C0000000 for testing printf(" 08x = %08x",fmt(intval)); -- since 16#C000000# is illegal according to the LRM printf(" 08h = %08h",fmt(intval)); printf(" 08u = %08u",fmt(intval)); sprintf( strout , "SPRINTF Read Location %d = %h",fmt(123456)&fmt(16#654321#)); printf("OUT STRING %s",fmt(strout)); write( ll , strout ); writeline(FSTR, ll); file_close( FSTR); wait for 1 ns; wait; end process; end TB;