-- $Source: /evtfs/home/tres/vhdl/play/RCS/min_vec_len.vhd,v $ -- Revision : $Revision: 1.7 $ -- Vector length functions -- Mike Treseler Sun Jul 30 14:59:23 2006 -- run assertions: vsim -c min_vec_len -do run ------------------------------------------------------------------------------- library ieee; use ieee.STD_LOGIC_1164.all; use ieee.numeric_std.all; package vec_functions is function vec_image(arg : std_logic_vector) return string; function vec_image(arg : unsigned) return string; function vec_image(arg : signed) return string; function min_len_uns(arg : natural) return natural; function power2(arg : unsigned) return boolean; function min_len_sgn(arg : integer) return natural; function nat2uns (arg : natural) return unsigned; function int2sgn (arg : integer) return signed; end package vec_functions; package body vec_functions is ------------------------------------------------------------------------------- function vec_image(arg : std_logic_vector) return string is -- recursive function call turns ('1','0','1') into "101" ------------------------------------------------------------------------------- constant arg_norm : std_logic_vector(1 to arg'length) := arg; constant center : natural := 2; -- 123 variable bit_image : string(1 to 3); -- '0' variable just_the_number : character; begin if (arg'length > 0) then bit_image := std_logic'image(arg_norm(1)); -- 3 chars: '0' just_the_number := bit_image(center); -- 1 char 0 return just_the_number -- first digit & vec_image(arg_norm(2 to arg_norm'length)); -- rest the same way else return ""; -- until "the rest" is nothing end if; end function vec_image; ------------------------------------------------------------------------------- function vec_image(arg : unsigned) return string is begin -- overloaded for unsigned return vec_image(std_logic_vector(arg)); end function vec_image; ------------------------------------------------------------------------------- function vec_image(arg : signed) return string is begin -- overloaded for signed return vec_image(std_logic_vector(arg)); end function vec_image; ------------------------------------------------------------------------------- function min_len_uns(arg : natural) return natural is begin case arg is when 1 | 0 => return 1; when others => return 1 + min_len_uns(arg/2); end case; end; ------------------------------------------------------------------------------- function power2(arg : unsigned) return boolean is variable bit_cnt_v : natural; begin bit_cnt_v := 0; scan : for i in arg'range loop if arg(i) = '1' then got_one: bit_cnt_v := bit_cnt_v + 1; end if; if bit_cnt_v > 1 then not_a_power_of_2 : return false; end if; end loop scan; just_one:if bit_cnt_v = 1 then is_a_power_of_2 : return true; else return false; end if just_one; end function power2; ------------------------------------------------------------------------------- function min_len_sgn(arg : integer) return natural is constant min_c : natural := min_len_uns(abs(arg)); begin case arg is when -1 | 0 => return 1; when others => if arg < -1 and power2(to_unsigned(-arg, min_c)) then -- case of ..., -8, -4, -2 return min_c; else return min_c +1; -- case of ... -9, -7, -6, -5, -3, 1, 2, 3, ... end if; end case; end; ------------------------------------------------------------------------------- function nat2uns (arg : natural) return unsigned is constant min_c : natural := min_len_uns(arg); subtype this_uns_t is unsigned(min_c -1 downto 0); constant ret_c : this_uns_t := to_unsigned(arg, min_c); begin return ret_c; end function nat2uns; ------------------------------------------------------------------------------- function int2sgn (arg : integer) return signed is subtype vec_t is signed(127 downto 0); -- eliminates tuncation warning variable arg_v : vec_t := to_signed(arg, vec_t'length); constant min_c : natural := min_len_sgn(arg); subtype this_sgn_t is signed(min_c -1 downto 0); begin return arg_v(this_sgn_t'range); end function int2sgn; ------------------------------------------------------------------------------- end package body vec_functions; ------------------------------------------------------------------------------- -- Verification of vec_functions: ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.vec_functions.all; ------------------------------------------------------------------------------- entity min_vec_len is end entity min_vec_len; ------------------------------------------------------------------------------- architecture sim of min_vec_len is begin -- architecture sim verify : process is begin -- debug_example:report vec_image(int2sgn(-8)); assert vec_image(nat2uns(0)) = "0" report "fix uns 0"; assert vec_image(nat2uns(1)) = "1" report "fix uns 1"; assert vec_image(nat2uns(4)) = "100" report "fix uns 4"; assert vec_image(nat2uns(5)) = "101" report "fix uns 5"; assert vec_image(nat2uns(15)) = "1111" report "fix uns 15"; assert vec_image(nat2uns(16)) = "10000" report "fix uns 16"; assert vec_image(int2sgn(-16)) = "10000" report "fix sgn -16"; assert vec_image(int2sgn(-15)) = "10001" report "fix sgn -15"; assert vec_image(int2sgn(-8)) = "1000" report "fix sgn -8"; assert vec_image(int2sgn(-3)) = "101" report "fix sgn -3"; assert vec_image(int2sgn(-2)) = "10" report "fix sgn -2"; assert vec_image(int2sgn(-1)) = "1" report "fix sgn -1"; assert vec_image(int2sgn(-0)) = "0" report "fix sgn -0"; assert vec_image(int2sgn(0)) = "0" report "fix sgn 0"; assert vec_image(int2sgn(1)) = "01" report "fix sgn 1"; report "assertion tests are complete"; wait; end process verify; end architecture sim; -- example session: -- > vsim -c min_vec_len -do run --Reading /flip/usr1/modeltech/tcl/vsim/pref.tcl --# 6.2a --# Loading /flip/usr1/modeltech/linux/../std.standard --# Loading /flip/usr1/modeltech/linux/../ieee.std_logic_1164(body) --# Loading /flip/usr1/modeltech/linux/../ieee.numeric_std(body) --# Loading work.min_vec_len(sim) --# run 1 --# ** Note: assertions tests are complete --# Time: 0 ns Iteration: 0 Instance: /min_vec_len