我想编写一个将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;
答案 0 :(得分:3)
现在显而易见的答案是if I mod 8 = 0 then
,但你不想这样做。
你在使用行if I(3 downto 0) = "000" then
做的是混合抽象级别:一个整数,以及一个整数的低级表示作为一个包。或严格来说,是一种可索引类型 - 即数组。
这是一个坏主意,因为它假设整数的表示形式可能有效也可能无效......具有讽刺意味的是,包括endian-ness。所以,VHDL不会让你这样做。
你可以做的是显式地“转换”为整数的表示,你可以确定什么位对应于什么,并对该具体表示执行低级操作,而不是抽象Integer
。 (假设您使用的计算机无论如何都具有该表示,“转换”没有时间或硬件资源的惩罚)。
有两种标准的表示形式。在numeric_std
库中,分别称为signed
和unsigned
。 '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的幂进行了明显的优化。