1-- 2-- Taken from rtl/commonlib/types_util.vhd of https://github.com/sergeykhbr/riscv_vhdl 3-- 4----------------------------------------------------------------------------- 5--! @file 6--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved. 7--! @author Sergey Khabarov - sergeykhbr@gmail.com 8--! @brief Package for common testbenches implementation. 9------------------------------------------------------------------------------ 10library ieee; 11use ieee.std_logic_1164.all; 12use ieee.numeric_std.all; 13library std; 14use std.textio.all; 15 16package types_util is 17 18function strlen(s: in string) return integer; 19function StringToUVector(inStr: string) return std_ulogic_vector; 20function StringToSVector(inStr: string) return std_logic_vector; 21function UnsignedToSigned(inUnsigned: std_ulogic_vector) return std_logic_vector; 22function SignalFromString(inStr: string; ind : integer ) return std_logic; 23function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector; 24 25function tost(v:std_logic_vector) return string; 26function tost(v:std_logic) return string; 27function tost(i : integer) return string; 28procedure print(s : string); 29 30end; 31 32package body types_util is 33 34 function strlen(s: in string) return integer is 35 variable n: integer:=0; variable sj: integer:=s'left; 36 begin 37 loop 38 if sj>s'right then exit; 39 elsif s(sj)=NUL then exit; --sequential if protects sj > length 40 else sj:=sj+1; n:=n+1; 41 end if; 42 end loop; 43 return n; 44 end strlen; 45 46 function SignalFromString(inStr: string; ind : integer ) return std_logic is 47 variable temp: std_logic := 'X'; 48 begin 49 if(inStr(inStr'high-ind)='1') then temp := '1'; 50 elsif(inStr(inStr'high-ind)='0') then temp := '0'; 51 end if; 52 return temp; 53 end function SignalFromString; 54 55 56 function StringToUVector(inStr: string) return std_ulogic_vector is 57 variable temp: std_ulogic_vector(inStr'range) := (others => 'X'); 58 begin 59 for i in inStr'range loop -- 60 if(inStr(inStr'high-i+1)='1') then temp(i) := '1'; 61 elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0'; 62 end if; 63 end loop; 64 return temp(inStr'high downto 1); 65 end function StringToUVector; 66 -- conversion function 67 68 function StringToSVector(inStr: string) return std_logic_vector is 69 variable temp: std_logic_vector(inStr'range) := (others => 'X'); 70 begin 71 for i in inStr'range loop -- 72 if(inStr(inStr'high-i+1)='1') then temp(i) := '1'; 73 elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0'; 74 end if; 75 end loop; 76 return temp(inStr'high downto 1); 77 end function StringToSVector; 78 79 function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector is 80 constant ss: string(1 to inStr'length) := inStr; 81 variable c : integer; 82 variable temp: std_logic_vector(7 downto 0) := (others => 'X'); 83 begin 84 c := character'pos(ss(idx+1)); 85 for i in 0 to 7 loop -- 86 temp(i) := to_unsigned(c,8)(i); 87 end loop; 88 return temp; 89 end function SymbolToSVector; 90 91 92 function UnsignedToSigned(inUnsigned: std_ulogic_vector) 93 return std_logic_vector is 94 variable temp: std_logic_vector(inUnsigned'length-1 downto 0) := (others => 'X'); 95 variable i: integer:=0; 96 begin 97 while i < inUnsigned'length loop 98 if(inUnsigned(i)='1') then temp(i) := '1'; 99 elsif(inUnsigned(i)='0') then temp(i) := '0'; 100 end if; 101 i := i+1; 102 end loop; 103 return temp; 104 end function UnsignedToSigned; 105 106 107 subtype nibble is std_logic_vector(3 downto 0); 108 109 function todec(i:integer) return character is 110 begin 111 case i is 112 when 0 => return('0'); 113 when 1 => return('1'); 114 when 2 => return('2'); 115 when 3 => return('3'); 116 when 4 => return('4'); 117 when 5 => return('5'); 118 when 6 => return('6'); 119 when 7 => return('7'); 120 when 8 => return('8'); 121 when 9 => return('9'); 122 when others => return('0'); 123 end case; 124 end; 125 126 127 function tohex(n:nibble) return character is 128 begin 129 case n is 130 when "0000" => return('0'); 131 when "0001" => return('1'); 132 when "0010" => return('2'); 133 when "0011" => return('3'); 134 when "0100" => return('4'); 135 when "0101" => return('5'); 136 when "0110" => return('6'); 137 when "0111" => return('7'); 138 when "1000" => return('8'); 139 when "1001" => return('9'); 140 when "1010" => return('a'); 141 when "1011" => return('b'); 142 when "1100" => return('c'); 143 when "1101" => return('d'); 144 when "1110" => return('e'); 145 when "1111" => return('f'); 146 when others => return('X'); 147 end case; 148 end; 149 150 151 function tost(v:std_logic_vector) return string is 152 constant vlen : natural := v'length; --' 153 constant slen : natural := (vlen+3)/4; 154 variable vv : std_logic_vector(0 to slen*4-1) := (others => '0'); 155 variable s : string(1 to slen); 156 variable nz : boolean := false; 157 variable index : integer := -1; 158 begin 159 vv(slen*4-vlen to slen*4-1) := v; 160 for i in 0 to slen-1 loop 161 if (vv(i*4 to i*4+3) = "0000") and nz and (i /= (slen-1)) then 162 index := i; 163 else 164 nz := false; 165 s(i+1) := tohex(vv(i*4 to i*4+3)); 166 end if; 167 end loop; 168 if ((index +2) = slen) then return(s(slen to slen)); 169 else return(string'("0x") & s(index+2 to slen)); end if; --' 170 end; 171 172 173 function tost(v:std_logic) return string is 174 begin 175 if to_x01(v) = '1' then return("1"); else return("0"); end if; 176 end; 177 178 179 function tost(i : integer) return string is 180 variable L : line; 181 variable s, x : string(1 to 128); 182 variable n, tmp : integer := 0; 183 begin 184 tmp := i; 185 if i < 0 then tmp := -i; end if; 186 loop 187 s(128-n) := todec(tmp mod 10); 188 tmp := tmp / 10; 189 n := n+1; 190 if tmp = 0 then exit; end if; 191 end loop; 192 x(1 to n) := s(129-n to 128); 193 if i < 0 then return "-" & x(1 to n); end if; 194 return(x(1 to n)); 195 end; 196 197 procedure print(s : string) is 198 variable L : line; 199 begin 200 L := new string'(s); writeline(output, L); 201 end; 202 203end; 204