是否可以在vhdl中的for循环中访问索引?错误:索引名称前缀类型natrual不是数组类型

时间:2017-01-15 16:44:06

标签: loops vhdl endianness

我想编写一个将big endian转换为little endian的小程序。因此我需要使用for循环。由于我只想每8位(1字节)进行一次切换,我需要使用某种模数。我不喜欢使用预定义的方法,并希望尽可能将其写为硬件。因此,我想访问迭代器变量并检查最后三位是否为零。因此,我知道完成了8次迭代。萨迪,我得到了错误消息:

  

索引名称前缀类型natural不是数组类型

我的代码如下:

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;

1 个答案:

答案 0 :(得分:3)

现在显而易见的答案是if I mod 8 = 0 then,但你不想这样做。

你在使用行if I(3 downto 0) = "000" then做的是混合抽象级别:一个整数,以及一个整数的低级表示作为一个包。或严格来说,是一种可索引类型 - 即数组。

这是一个坏主意,因为它假设整数的表示形式可能有效也可能无效......具有讽刺意味的是,包括endian-ness。所以,VHDL不会让你这样做。

你可以做的是显式地“转换”为整数的表示,你可以确定什么位对应于什么,并对该具体表示执行低级操作,而不是抽象Integer 。 (假设您使用的计算机无论如何都具有该表示,“转换”没有时间或硬件资源的惩罚)。

有两种标准的表示形式。在numeric_std库中,分别称为signedunsigned。 'signed'是明确的2-s补码,unsigned很简单 - 都是std_logic类型的数组,因此是可索引的。

use IEEE.numeric_std.all;

你可以阅读这个包的来源,所以没有假设。 (或者你可以写一个不同的包,体现你需要的约定。但没有人这样做......)

因此,您可以将循环变量转换为5位unsigned并将索引转换为...

if to_unsigned(I,5)(2 downto 0) = "000" then

请注意,由于数组长度不匹配,原始比较将始终返回False。

最后,综合工具并不愚蠢;无论如何,他们安全地对mod 2的幂进行了明显的优化。