Hi - I'm a long-time Verilog coder coming up on VHDL. What I need to do in VHDL is
signal data : std_logic_vector (31 downto 0);
signal sel : std_logic_vector (4 downto 0);
signal res : std_logic;
process (data,sel)
begin
res <= data(sel);
end process;
But it doesn't like me using sel as a bit-select. What's the right way to do this?
- A couple of points: Type std_logic_vector has no numeric interpretation at all, it is simply a collection of bits.
- Selection of something from an array such as data(sel), requires that 'sel' be an integer.
The most straightforward approach is that sel be defined as an integer in the appropriate range. You could do it like this:
signal sel: integer range 0 to 31;
Or, since 'sel'l must always be in the same range as the number of bits in 'data', then a more well documented way of declaring sel that makes it abundantly clear to the reader what sel is would be:
signal sel: integer range data'range;
Somewhat related, but a bit off topic, is that in VHDL if you want a collection of bits that do have a numeric interpretation you want to use the package ieee.numeric_std. Defined in that package are the types 'unsigned' and 'signed'. Then you can declare signals like this...
signal sel: unsigned(4 downto 0);
Now you can do the following types of things:
- if (sel = 1) ...
- sel <= sel + 3;
However, 'unsigned' is not an integer so for your problem you would still need to convert it to an integer like this...
res <= data(to_integer(sel)); -- Where 'sel' is unsigned(4 downto 0);
If changing the type of 'sel' is not possible for some reason, and you're stuck with having it be a std_logic_vector, then you have to convert it to an integer. This is conceptually a two step process
- First apply the appropriate numeric interpretation for how you want that collection of bits to be treated. You do this by converting the std_logic_vector to unsigned (in your case), but could also be signed in some other applications:
- Convert the unsigned/signed type to an integer
For your particular problem, it woul look like this...
res <= data(to_integer(unsigned(sel)));
If that looks too wordy, remember that the reason for the wordiness is because the signal 'sel' was actually declared with an inappropriate type; it was declared as a collection of bits (std_logic_vector), rather than what it truly is (an integer that indexes through the range of 'data'). Had 'sel' been declared with the appropriate data type as I showed at the start, there is no extra wordy baggage. Note: While there is extra typing to apply these type conversions, there is absolutely no hardware generated. It simply allows the compiler to do proper type checking to see if you're using the signals appropriately.
Kevin Jennings