2

I'm facing this problem , i'm asked to implement a function in VHDL that takes an integer and returns a bit_vector , assumed that this integer is represented by 4 bits.

i don't want to use already built in function, i have to code the function.

I have made a function to convert from bit_vector to integer which was kinda of easy, but im stuck here :S

Any ideas how can i do it ?

2 Answers 2

4

Morten's is the correct answer but it's sometimes worth being open to alternative approaches...

As the question relates to a small (4-bit) range, a lookup table becomes attractive : I have assumed unsigned integers but it's easy to adapt.

subtype bv4 is bit_vector(3 downto 0);
constant LUT : array(0 to 15) of bv4 := (
   "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
   "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111");

function to_bv(n : natural) return bit_vector is
begin
   return LUT(n);
end to_bv;

This will normally synthesise as you would hope rather than actually creating a ROM!

Sign up to request clarification or add additional context in comments.

1 Comment

yes this one is correct to i tried it , but it is not very useful when it comes to higher than 4 bits , but thanks for the effort mate :)
2

The VHDL standard packages is good inspiration for home brewed functions, and the numeric_bit package defines the to_unsigned function for conversion of natural type to unsigned type, which is the function VHDL actually uses for conversion to bit_vector. The function is implemented as:

function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED is
  variable RESULT: UNSIGNED(SIZE-1 downto 0);
  variable I_VAL: NATURAL := ARG;
begin
  if (SIZE < 1) then return NAU;
  end if;
  for I in 0 to RESULT'LEFT loop
    if (I_VAL mod 2) = 0 then
      RESULT(I) := '0';
    else 
      RESULT(I) := '1';
    end if;
    I_VAL := I_VAL/2;
  end loop;
  if not(I_VAL =0) then
    assert NO_WARNING
        report "NUMERIC_BIT.TO_UNSIGNED: vector truncated"
        severity WARNING;
  end if;
  return RESULT;
end TO_UNSIGNED;

The initial if (SIZE < 1) and final if not(I_VAL =0) checks may be removed, if it is known that the function is never used with values that makes the checks relevant.

This leaves the for I in 0 to RESULT'LEFT loop that creates one result bit per iteration.

Based on Brian's answer, the constant LUT can be initialized using the TO_UNSIGNED function, to avoid the hand written literals:

function to_bv(n, size : natural) return bit_vector is

  type bv_arr_t is array (0 to 2 ** size - 1) of bit_vector(size - 1 downto 0);

  function bv_arr_init(size : natural) return bv_arr_t is
    variable res_v : bv_arr_t;
  begin
    for i in 0 to 2 ** size - 1 loop
      res_v(i) := bit_vector(TO_UNSIGNED(i, size));
    end loop;
    return res_v;
  end function;

  constant LUT : bv_arr_t := bv_arr_init(size);

begin
  return LUT(n);
end to_bv;

3 Comments

your answer did helped me a lot , thanks a lot mate , but can you tell me how exactly did you get this code from the ise library >?
Initialising LUTs from a function is a very useful technique too. My point was that in this case the explicit literals are probably simpler and less work!
@MSherin: Source files for packages can be found in VHDL Supplemental Material

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.