Hexadecimal value (literal) as function parameter, is it possible?

Discussion in 'VHDL' started by wimille, Apr 12, 2013.

  1. wimille

    wimille Guest


    I'm currently writting a package file for my design and my testbenchs, and i need to write a function to resize an vector.

    I write the function as follows:

    function resize ( vec : in std_logic_vector; size : in natural) return std_logic_vector is
    variable resized : std_logic_vector( size-1 downto 0) := (others => '0');
    variable len : natural := 0;
    len := vec'length;
    if ( len = size ) then
    resized := vec;
    elsif ( len > size ) then
    resized := vec(size-1 downto 0);
    elsif ( len < size ) then
    resized := resized(size-1 downto len) & vec;
    end if;
    return resized;
    end function resize;

    But i need to update or to overload this function in order to allow this type of operation:

    toto <= resize( x"AAAA", 10);

    Because if i write this now, i've got this error in Modelsim:
    # ** Fatal: (vsim-3607) Slice range direction (downto) does not match slice prefix direction (to).

    Thanks for your help
    wimille, Apr 12, 2013
    1. Advertisements

  2. wimille

    KJ Guest

    I'd suggest that you don't reinvent the wheel. Use the ieee.numeric_std library which already has resize functions for signed and unsigned types which can be converted, if necessary, to std_logic_vector if you must use that type.

    use ieee.numeric.std.all;
    toto <= std_logic_vector(resize(43690, 10)); -- One way to do it
    toto <= std_logic_vector(resize(16#AAAA#, 10)); -- Another way to do it

    Kevin Jennings
    KJ, Apr 12, 2013
    1. Advertisements

  3. Le 12/04/2013 14:46, a écrit :

    The problem comes from the line "resized := vec(size-1 downto 0);" that
    needs your input object vec to have a descending range. Litteral
    constants such as x"AAAA" have an ascending range so you can't pass them
    to your function.
    A solution would be to use an intermediate variable :

    function resize ( vec : in std_logic_vector; size : in natural) return
    std_logic_vector is
    constant LEN : natural := vec'length;
    variable i_vec : std_logic_vector(LEN-1 downto 0) := vec;
    variable resized : std_logic_vector( size-1 downto 0) := (others => '0');

    and then use i_vec instead of vec in the function.

    Or you can use the resize functions that already exist in the
    numeric_std package as Kevin suggested.

    Nicolas Matringe, Apr 13, 2013
  4. wimille

    Andy Guest

    I agree with Nicolas. This is sometimes called "range normalization", and if you look at the reference implementations of IEEE packages, it is very commonly used.

    To add to what Kevin said, if your tools support VHDL-2008, you can use the ieee.numeric_std_unsigned package; it defines resize() for std_logic_vectors.

    Numeric_std_unsigned applies numeric_std's functions and operators for the unsigned type, to std_logic_vector. It also defines a to_std_logic_vector(natural) and similar aliases to_stdlogicvector(), to_slv(), etc.

    Numeric_std_unsigned is similar in concept to the debunked "std_logic_arith" package, but is official and governed by the standard, ensuring compatibility across tool vendors.

    If your tools do not support VHDL-2008, call the vendor and complain. Loudly.

    Andy, Apr 15, 2013
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.