I want to write a small program that converts big endian to little endian. Therefore I need to use a for loop. Since I only want to do the switch every 8 bit (1 Byte) i need to use some kind of modulo. I am not a fan of using predefined methods and would like to write it as hardware near as possible. Therefore I wanted to access the iterator variable and check if the last three bits are zero. Thus, I know that 8 iterations are done. Saddy, I get the erro message:
Indexed name prefix type natural is not an array type
My code is the following:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TOP is
Port ( INPUT : in STD_LOGIC_VECTOR (32 downto 0);
CLK : in STD_LOGIC;
OUTPUT : out STD_LOGIC_VECTOR (32 downto 0));
end TOP;
architecture Behavioral of TOP is
begin
S: process(CLK)
begin
if rising_edge(CLK) then
for I in INPUT' range loop
--every 8 bit
if I(3 downto 0) = "000" then
OUTPUT(OUTPUT'left -I*8 downto OUTPUT'left - (I+1)*8) <= INPUT((I+1)*7 downto I*7);
end if;
end loop;
end if;
end process S;
end Behavioral;
Now the obvious answer would be if I mod 8 = 0 then
but you don't want to do that.
What you are doing with the line if I(3 downto 0) = "000" then
is mixing levels of abstraction : an integer, and a low level representation of an integer as a bag of bits. Or strictly speaking, an indexable type - i.e. an array.
That is a bad idea because it makes assumptions about the representation fo an integer that may or may not be valid ... ironically, including endian-ness. So, VHDL won't let you do that.
What you can do is explicitly "convert" to a representation of an integer, where you can be certain what bit corresponds to what, and perform the low level operations on that concrete representation, instead of the abstract Integer
. (Assuming the computer you're using has that representation anyway, the "conversion" has no penalty in time or hardware resources).
There are two standard such representations. in the numeric_std
library, called signed
and unsigned
respectively. The 'signed' one is explicitly 2-s complement and the unsigned
is straightforward - both are arrays of std_logic types, therefore indexable.
use IEEE.numeric_std.all;
And you can read the source of this package, so there are no assumptions to make. (Or you could write a different package embodying the conventions you need instead. But nobody does that...)
So you could convert the loop variable to a 5-bit unsigned
and index into that...
if to_unsigned(I,5)(2 downto 0) = "000" then
Note that the original comparison would ALWAYS return False because of the array length mismatch.
Finally, synthesis tools aren't stupid; they safely make the obvious optimisation on mod
power-of-2 anyway.