ISE 14.7在合成时在后续行返回以下警告,最终导致错误: “宽度不匹配。< temp>宽度为8位,但指定的表达式为128位宽。”
temp <= padding_start_s((((i_pad+1)*8)-1) downto (i_pad*8));
问题似乎与for循环有关。我想要做的是填充N位128位的输入信号。最终收到一个非完整的128位信号,我想检测它最终结束的位置然后添加填充。当然,缺少一些代码,但这应该是相关的东西。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.NUMERIC_STD.all;
library work;
use work.keccak_globals.all;
entity Keccak_padder is
port (
clk_i : in std_logic;
data_i : in std_logic_vector(127 downto 0);
rst_n : in std_logic;
start_i : in std_logic;
end_i : in std_logic;
state_vector_o : out std_logic_vector(r-1 downto 0);
state_vector_valid_o : out std_logic;
long_message_o : out std_logic
);
end Keccak_padder;
architecture Behavioral of Keccak_padder is
signal word_count : integer range 1 to 16:=1;
signal pad_count : integer range 0 to 3:=0;
signal i_pad : integer range 0 to 15;
signal word_count : integer range 1 to 16:=1;
signal padding_start_s : std_logic_vector(127 downto 0):=(others=>'0');
signal temp : std_logic_vector(7 downto 0);
constant zero_vector : std_logic_vector(7 downto 0):=(others=>'0');
signal start_pad : std_logic;
process(clk_i, rst_n, fsm_state, pad_count, start_pad, padding_start_s)
begin
if rising_edge(clk_i) then
case fsm_state is
when IDLE =>
...
when TRANSMIT =>
...
when RECEIVE =>
if (pad_count = 1) then
state_vector_o((r-1-(data_i'length * (word_count - 1))) downto (r-(data_i'length * (word_count)))) <= temp;
pad_count <= 0;
fsm_state <= IDLE;
start_pad <= '0';
elsif (start_pad = '1') then
temp <= padding_start_s((((i_pad+1)*8)-1) downto (i_pad*8));
pad_count <= pad_count + 1;
end if;
for i in 15 downto 0 loop
if (padding_start_s((((i+1)*8)-1) downto ((i)*8)) = zero_vector) then
i_pad <= i;
start_pad <= '1';
exit;
end if;
end loop;
end case;
end if;
end process;
所以我最终要问的是:我如何找到解决方法,为什么这是一个问题?在信号分配中削减范围是错误的吗?
谢谢!
答案 0 :(得分:1)
如果没有Minimal, Complete, and Verifiable example,答案就会被击中或遗漏,这是一个综合问题,而不是VHDL语言语法或语义问题。
正如Brian所评论的那样,对于8位宽的值,临时分配是16:1的多路复用,因此可以简化索引。甚至超过布莱恩建议:
type byte_array_16 is array (15 downto 0) of std_logic_vector (7 downto 0);
signal padding_bytes: byte_array_16;
begin
padding_bytes <= byte_array_16'(
padding_start_s(127 downto 120), padding_start_s(119 downto 112),
padding_start_s(111 downto 104), padding_start_s(103 downto 96),
padding_start_s( 95 downto 88), padding_start_s( 87 downto 80),
padding_start_s( 79 downto 72), padding_start_s( 71 downto 64),
padding_start_s( 63 downto 56), padding_start_s( 55 downto 48),
padding_start_s( 47 downto 40), padding_start_s( 39 downto 32),
padding_start_s( 31 downto 24), padding_start_s( 23 downto 16),
padding_start_s( 15 downto 8), padding_start_s( 7 downto 0)
);
TEST1: -- temp assignment expression
process
variable i_pad: integer range 0 to 15; -- overloads signal i_pad
begin
for i in 0 to 15 loop
i_pad := i;
-- temp <= padding_start_s((((i_pad + 1) * 8) - 1) downto (i_pad * 8));
temp <= padding_bytes(i_pad);
wait for 0 ns; -- temp assignment takes effect next delta cycle
end loop;
report "Test 1, temp assignment, no bounds errors";
wait;
end process;
对padding_bytes的赋值就像C中的union一样,除了它只有一种方式。它也不会增加硬件负担。
因此,i_pad值确定是来自特定端的优先级编码器,其中一串字节识别器将值与常量zero_vector进行比较。这16个识别器(for循环将在合成中解开)得到优化,只需查找所有'0'。
除了识别器之外,还有一个16到4个优先编码器,用于生成i_pad和start_pad,用于指定任何发现全部为0的识别器。
但是,你选择输入识别器的所有算法都是多毛的。您可以使用相同的单向联合修复它:
FIND_FIRST_ZERO_BYTE:
process
begin
start_pad <= '0';
for i in 15 downto 0 loop
if padding_bytes(i) = zero_vector then
i_pad <= i;
start_pad <= '1';
exit;
end if;
end loop;
wait;
end process;
这消除了因为i_pad是一个信号所需的大量算法。