0
votes

I want to get binary std_logic_vector from integer inside the generate.

For example,

0 -> 0000

1 -> 0001

2 -> 0010

...

15 -> 1111

I could write 16 if-else statements for each integer number, but I don't like this idea. (What if I will have much more than 16 integer numbers?)

I've tried to use two methods, but neither of them works: address and hit are both std_logic_vector

G_1 : for i in 0 to 15 generate
    address <= conv_std_logic_vector(i, 4) when hit(i) = '1';
end generate G_1;   

G_2 : for i in 0 to 15 generate
    address <= std_logic_vector(to_unsigned(i, 4)) when hit(i) = '1';
end generate G_2;

Also I noticed that if I use number instead of the i, it works. (Example: I get "0101" when I use conv_std_logic_vector(5, 4))

What am I doing wrong? Is there any possible way to do it using vhdl?

1

1 Answers

2
votes

For a start, do not use ieee.std_logic_arith.all. Instead, use ieee.numeric_std.all, and get rid of any nasty conv_integer functions; the preferred style is to use types like unsigned, and then convert or cast these as you have in your second code example.

Moving on to your loop, you are using generate loop:

G_1 : for i in 0 to 15 generate
  address <= conv_std_logic_vector(i, 4) when hit(i) = '1';
end generate G_1;

This will generate 16 lines of the form:

address <= conv_std_logic_vector(0, 4) when hit(0) = '1';
address <= conv_std_logic_vector(1, 4) when hit(1) = '1';
address <= conv_std_logic_vector(2, 4) when hit(2) = '1';

etc. Since each concurrent assignment infers its own process, your design will have multiple drivers on the address signal, which is not allowed in a synthesis-eligible design.

It seems like the objective is to set address according to the lowest set ('1') bit in the hit vector. This is called a priority encoder. Something like this would be better:

process (hit)
begin
  for i in 0 to 15 loop
    address <= (others => '0');  -- Default assignment, any later assignment takes priority
    if (hit(i) = '1') then
      address <= std_logic_vector(to_unsigned(i, address`length));
      exit;
    end if;
  end loop;
end process;

Since address seems to represent an unsigned number, you could use type unsigned for this signal, and save a type cast.