-- package vs_util has conversion functions, etc. -- -- Written by Rob Anderson, VLSI 1994 -- library ieee; use ieee.std_logic_1164.all; use std.textio.all; --******************************************************* package vs_util is function stdv_to_hex(inp:std_logic_vector) return string; function stdl_to_ch(inp:std_logic) return character; function ch_to_stdl(inp:character) return std_logic; function hex_to_stdv(inp:character) return std_logic_vector; function hex_to_stdvf(inp:character) return std_logic_vector; procedure rndm(variable rnd_seed: inout integer); procedure rnd_stdv(variable seed: inout integer; stdv: out std_logic_vector); procedure read_stdl(variable l:inout line;tmp_stdl:out std_logic); procedure readf_stdl(variable l:inout line;tmp_stdl:out std_logic); procedure read_stdv(variable l:inout line;ref_sig:std_logic_vector; tmp_stdv: out std_logic_vector); procedure readf_stdv(variable l:inout line;ref_sig:std_logic_vector; tmp_stdv: out std_logic_vector); function cmpv(l,r:std_logic_vector) return boolean; function cmpl(l,r:std_logic) return boolean; -- writeline string procedure wlstr(f:out text; svalue:string); -- writeline bit to qsim procedure wlbqs(f:out text; bvalue:std_logic; svalue:string); procedure wlvqs(f:out text; vvalue:std_logic_vector; svalue:string); procedure wlbtqs(f:out text; bvalue:std_logic; svalue:string); procedure wlvtqs(f:out text; vvalue:std_logic_vector; svalue:string); function isabv(val:std_logic_vector) return boolean; function isab(val:std_logic) return boolean; end vs_util; --************************************************************* package body vs_util is function isab(val:std_logic) return boolean is begin return ((val='0') or (val='1')); end; function isabv(val:std_logic_vector) return boolean is begin for i in val'range loop if ((val(i)/='0') and (val(i)/='1')) then return false; end if; end loop; return true; end; procedure wlstr(f:out text; svalue:string) is variable l:line; begin write(l,svalue); writeline(f,l); end; procedure wlbqs(f:out text; bvalue:std_logic; svalue:string) is variable l:line; begin case bvalue is when '0'=> write(l,string'("L " & svalue)); when '1'=> write(l,string'("H " & svalue)); when others=> assert false report "wlbqs --> bad input; bvalue='" & stdl_to_ch(bvalue) & "'" severity failure; end case; writeline(f,l); end; procedure wlvqs(f:out text; vvalue:std_logic_vector; svalue:string) is variable l:line; variable stmp:string(((vvalue'length+3)/4) downto 1); begin stmp:=stdv_to_hex(vvalue); for i in stmp'range loop assert stmp(i) /= 'U' report "wlvqs --> bad input; vvalue=" & stmp severity failure; end loop; write(l,"sv " & svalue & " 'H" & stmp); writeline(f,l); end; procedure wlbtqs(f:out text; bvalue:std_logic; svalue:string) is variable l:line; begin case bvalue is when '0'=> write(l,string'("T " & svalue & " 'B0")); when '1'=> write(l,string'("T " & svalue & " 'B1")); when others=> assert false report "wlbtqs --> bad input; bvalue='" & stdl_to_ch(bvalue) & "'" severity failure; end case; writeline(f,l); end; procedure wlvtqs(f:out text; vvalue:std_logic_vector; svalue:string) is variable l:line; variable stmp:string(((vvalue'length+3)/4) downto 1); begin stmp:=stdv_to_hex(vvalue); for i in stmp'range loop assert stmp(i) /= 'U' report "wlvtqs --> bad input; vvalue=" & stmp severity failure; end loop; write(l,"T " & svalue & " 'H" & stmp); writeline(f,l); end; -- assume r is test value, so if it is x or u, equals -- l is output of circuit under test... function cmpv(l,r:std_logic_vector) return boolean is alias la:std_logic_vector(l'length-1 downto 0) is l; alias ra:std_logic_vector(r'length-1 downto 0) is r; variable equal:boolean:=true; variable ch1:character; begin if la'length /= ra'length then return false; end if; for i in la'range loop ch1:=stdl_to_ch(la(i)); case ra(i) is when '0'=> equal:= not((ch1='1') or (ch1='Z')); when '1'=> equal:= not((ch1='0') or (ch1='Z')); when 'Z'=> equal:= not((ch1='0') or (ch1='1')); when others=>null; end case; exit when not equal; end loop; return equal; end; function cmpl(l,r:std_logic) return boolean is variable equal:boolean:=true; variable ch1:character; begin ch1:=stdl_to_ch(l); case r is when '0'=> equal:= not((ch1='1') or (ch1='Z')); when '1'=> equal:= not((ch1='0') or (ch1='Z')); when 'Z'=> equal:= not((ch1='0') or (ch1='1')); when others=>null; end case; return equal; end; function hex_to_stdv(inp:character) return std_logic_vector is begin case inp is when 'X'|'x'=>return "XXXX"; when '0'=>return "0000"; when '1'=>return "0001"; when '2'=>return "0010"; when '3'=>return "0011"; when '4'=>return "0100"; when '5'=>return "0101"; when '6'=>return "0110"; when '7'=>return "0111"; when '8'=>return "1000"; when '9'=>return "1001"; when 'A'|'a'=>return "1010"; when 'B'|'b'=>return "1011"; when 'C'|'c'=>return "1100"; when 'D'|'d'=>return "1101"; when 'E'|'e'=>return "1110"; when 'F'|'f'=>return "1111"; when 'Z'|'z'=>return "ZZZZ"; when '-'=>return "----"; when 'U'|'u'=>return "UUUU"; when others=>return "UUUU"; end case; end; -- safe function - return 0 when in doubt function hex_to_stdvf(inp:character) return std_logic_vector is begin case inp is when '0'=>return "0000"; when '1'=>return "0001"; when '2'=>return "0010"; when '3'=>return "0011"; when '4'=>return "0100"; when '5'=>return "0101"; when '6'=>return "0110"; when '7'=>return "0111"; when '8'=>return "1000"; when '9'=>return "1001"; when 'A'|'a'=>return "1010"; when 'B'|'b'=>return "1011"; when 'C'|'c'=>return "1100"; when 'D'|'d'=>return "1101"; when 'E'|'e'=>return "1110"; when 'F'|'f'=>return "1111"; when others=>return "0000"; end case; end; -- safe reader - change everything to '0' ulnless it is '1' procedure readf_stdv(variable l:inout line;ref_sig:std_logic_vector; tmp_stdv: out std_logic_vector) is -- assume descending ranges variable tmp_asc:string(((ref_sig'length +3)/4) downto 1); variable i,j,k:integer; variable ch1:character; variable stdv4:std_logic_vector(3 downto 0); begin i:=tmp_asc'left; loop if (l=null or l'length=0) then assert false report "premature end of line, procedure readf_stdv" & "tmp_asc:" & tmp_asc & ":" severity failure; end if; read(l,ch1); next when ((ch1 = ' ') or (ch1 = ht)); tmp_asc(i):=ch1; i:=i-1; exit when i=0; end loop; -- convert and fill in tmp_stdv for i in tmp_asc'right to tmp_asc'left loop stdv4:=hex_to_stdvf(tmp_asc(i)); j:=(i-1)*4; k:=j+3; if k >= ref_sig'length then k:= ref_sig'length -1; end if; for i in j to k loop tmp_stdv(i) := stdv4(i-j); end loop; end loop; end; procedure read_stdv(variable l:inout line;ref_sig:std_logic_vector; tmp_stdv: out std_logic_vector) is -- assume descending ranges variable tmp_asc:string(((ref_sig'length +3)/4) downto 1); variable i,j,k:integer; variable ch1:character; variable stdv4:std_logic_vector(3 downto 0); begin i:=tmp_asc'left; loop if (l=null or l'length=0) then assert false report "premature end of line, procedure read_stdv" & "tmp_asc:" & tmp_asc & ":" severity failure; end if; read(l,ch1); next when ((ch1 = ' ') or (ch1 = ht)); tmp_asc(i):=ch1; i:=i-1; exit when i=0; end loop; -- convert and fill in tmp_stdv for i in tmp_asc'right to tmp_asc'left loop stdv4:=hex_to_stdv(tmp_asc(i)); j:=(i-1)*4; k:=j+3; if k >= ref_sig'length then k:= ref_sig'length -1; end if; for i in j to k loop tmp_stdv(i) := stdv4(i-j); end loop; end loop; end; function ch_to_stdl(inp:character) return std_logic is begin case inp is when 'U'=>return 'U'; when 'X'=>return 'X'; when '0'=>return '0'; when '1'=>return '1'; when 'Z'=>return 'Z'; when 'W'=>return 'W'; when 'L'=>return 'L'; when 'H'=>return 'H'; when '-'=>return '-'; when others=> assert false report "bad input character:" & inp severity failure; end case; end; -- safe function returns 0 when in doubt function ch_to_stdlf(inp:character) return std_logic is begin case inp is when '0'=>return '0'; when '1'=>return '1'; when 'U' | 'X' | 'Z' | 'W' | 'L' | 'H' | '-' => return '0'; when others=> assert false report "bad input character:" & inp severity failure; end case; end; procedure rndm(variable rnd_seed: inout integer) is begin rnd_seed:=((rnd_seed * 25173)+13849) mod 65536; end; procedure rnd_stdv(variable seed: inout integer; stdv: out std_logic_vector) is constant mlen:integer:= stdv'length; alias sv:std_logic_vector(mlen-1 downto 0) is stdv; variable k:integer:=mlen / 16; variable krem:integer:=mlen rem 16; variable llim,stmp:integer; begin llim:=0; while k>0 loop rndm(seed); stmp:=seed; for i in 0 to 15 loop if ((stmp rem 2)/=0) then sv(llim):='1'; else sv(llim):='0'; end if; stmp:=stmp / 2; llim:=llim+1; end loop; llim:=llim+1; k:=k-1; end loop; rndm(seed); stmp:=seed; while krem>0 loop if ((stmp rem 2)/=0) then sv(llim):='1'; else sv(llim):='0'; end if; stmp:=stmp / 2; llim:=llim+1; krem:=krem-1; end loop; end; procedure read_stdl(variable l:inout line;tmp_stdl:out std_logic) is variable ch1:character; begin loop if (l=null or l'length=0) then assert false report "premature end of line, procedure read_stdl" severity failure; end if; read(l,ch1); next when ((ch1 = ' ') or (ch1 = ht)); exit; end loop; tmp_stdl := ch_to_stdl(ch1); end; -- safe reader procedure readf_stdl(variable l:inout line;tmp_stdl:out std_logic) is variable ch1:character; begin loop if (l=null or l'length=0) then assert false report "premature end of line, procedure read_stdl" severity failure; end if; read(l,ch1); next when ((ch1 = ' ') or (ch1 = ht)); exit; end loop; tmp_stdl := ch_to_stdlf(ch1); end; function stdl_to_ch(inp:std_logic) return character is begin case inp is when 'U'=>return 'U'; when 'X'=>return 'X'; when '0'=>return '0'; when '1'=>return '1'; when 'Z'=>return 'Z'; when 'W'=>return 'W'; when 'L'=>return 'L'; when 'H'=>return 'H'; when '-'=>return '-'; end case; end; function stdv_to_hex(inp:std_logic_vector) return string is alias vec: std_logic_vector(inp'length downto 1) is inp; variable tmpstr:string(((inp'length+3)/4) downto 1); variable svec:std_logic_vector(3 downto 0); variable j,k:integer; variable ch1:character; begin for i in 1 to ((inp'length+3)/4) loop j:=((i-1)*4)+1; if ((j+3)>inp'length) then svec:="0000"; for k in j to inp'length loop svec(k-j):=vec(k); end loop; else svec:=vec((j+3) downto j); end if; case svec is when "0000"=>ch1:='0'; when "0001"=>ch1:='1'; when "0010"=>ch1:='2'; when "0011"=>ch1:='3'; when "0100"=>ch1:='4'; when "0101"=>ch1:='5'; when "0110"=>ch1:='6'; when "0111"=>ch1:='7'; when "1000"=>ch1:='8'; when "1001"=>ch1:='9'; when "1010"=>ch1:='A'; when "1011"=>ch1:='B'; when "1100"=>ch1:='C'; when "1101"=>ch1:='D'; when "1110"=>ch1:='E'; when "1111"=>ch1:='F'; when "ZZZZ"=>ch1:='Z'; when others=>ch1:='U'; end case; tmpstr(i):=ch1; end loop; return tmpstr; end; end vs_util;