在 VHDL 中使用外部信号退出循环
Exit a loop using external signal in VHDL
我正在尝试将一个数据块(16 字节,4 个字)从我的实体缓存写入我的其他实体内存。
内存是字节寻址的,所以我一次只能写1个字节。
当写入一个字节后,内存将更新 mem_done 为 1。
要写一个区块,我需要:
写一个字节,
等待mem_done设置(内存实体),
increment mem_address(下一个地址给内存),byte_count ,每 4 个字节递增 word_offset(缓存中单词的偏移量)。
循环直到写完所有单词(word_offset = words_per_block-1).
在使用 Xilinx 进行综合时,我收到 wait_loop 的错误 "Non-static loop limit exceeded"。
我不能在循环中使用 wait until 语句(错误:不允许使用多个等待语句)。
我不能使用 FSM,因为状态转换会浪费一个时钟周期(而且我有时序限制)。
在不打破循环限制的情况下,我怎样才能做到这一点?
-- block dirty in memory, write cache block back to memory
mem_enable <= '1'; -- out to memory, enable memory transfer
mem_rw <= '1'; -- out to memory. read/write bit
mem_addr_tmp <= cpu_addr; -- internal, address to write to
word_offset <= 0; -- internal, offset in cache
byte_count <= 31;
burst_loop: loop
-- Transfer 1 byte of data
mem_data <= CACHE(index).data(word_offset)(byte_count downto byte_count-7);
mem_addr <= mem_addr_tmp;
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
-- Update address, word offset, byte count
mem_addr_tmp <= std_logic_vector(to_unsigned(to_integer(unsigned(mem_addr_tmp)) + 1, mem_addr_tmp'length));
if (byte_count mod 4 = 0) then -- a word has been transfered, increment word_offset
word_offset <= word_offset + 1;
byte_count <= 31;
else -- a byte of a word has been transfered
byte_count <= byte_count - 7;
end if;
exit burst_loop when (mem_done = '1' and word_offset = words_per_block-1);
end loop burst_loop;
mem_enable <= '0';
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
当mem_done = '0'
时,这是一个无限循环。在 VHDL 中,语句的 执行时间是瞬时的 ,wait 语句除外。因此,如果进入循环时 mem_done 为 '0',它将永远不会退出,因为时间永远不会前进。
此外,wait 语句通常是不可综合的。我们使用状态机在 VHDL 中产生顺序语句(否则,语句是并行执行的)。
最后,VHDL(用于合成)中的loops用于表示spatial循环,你将它们用于temporal 循环,就像在编程语言中一样(VHDL 是一种硬件描述语言)。如果愿意,循环总是展开的,只是提供了一种更简洁的方式来编写多个相似的语句。在模拟中,您可以像在编程语言中一样通过使用等待语句来使用循环。
我正在尝试将一个数据块(16 字节,4 个字)从我的实体缓存写入我的其他实体内存。
内存是字节寻址的,所以我一次只能写1个字节。 当写入一个字节后,内存将更新 mem_done 为 1。
要写一个区块,我需要:
写一个字节,
等待mem_done设置(内存实体),
increment mem_address(下一个地址给内存),byte_count ,每 4 个字节递增 word_offset(缓存中单词的偏移量)。
循环直到写完所有单词(word_offset = words_per_block-1).
在使用 Xilinx 进行综合时,我收到 wait_loop 的错误 "Non-static loop limit exceeded"。
我不能在循环中使用 wait until 语句(错误:不允许使用多个等待语句)。
我不能使用 FSM,因为状态转换会浪费一个时钟周期(而且我有时序限制)。
在不打破循环限制的情况下,我怎样才能做到这一点?
-- block dirty in memory, write cache block back to memory
mem_enable <= '1'; -- out to memory, enable memory transfer
mem_rw <= '1'; -- out to memory. read/write bit
mem_addr_tmp <= cpu_addr; -- internal, address to write to
word_offset <= 0; -- internal, offset in cache
byte_count <= 31;
burst_loop: loop
-- Transfer 1 byte of data
mem_data <= CACHE(index).data(word_offset)(byte_count downto byte_count-7);
mem_addr <= mem_addr_tmp;
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
-- Update address, word offset, byte count
mem_addr_tmp <= std_logic_vector(to_unsigned(to_integer(unsigned(mem_addr_tmp)) + 1, mem_addr_tmp'length));
if (byte_count mod 4 = 0) then -- a word has been transfered, increment word_offset
word_offset <= word_offset + 1;
byte_count <= 31;
else -- a byte of a word has been transfered
byte_count <= byte_count - 7;
end if;
exit burst_loop when (mem_done = '1' and word_offset = words_per_block-1);
end loop burst_loop;
mem_enable <= '0';
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
当mem_done = '0'
时,这是一个无限循环。在 VHDL 中,语句的 执行时间是瞬时的 ,wait 语句除外。因此,如果进入循环时 mem_done 为 '0',它将永远不会退出,因为时间永远不会前进。
此外,wait 语句通常是不可综合的。我们使用状态机在 VHDL 中产生顺序语句(否则,语句是并行执行的)。
最后,VHDL(用于合成)中的loops用于表示spatial循环,你将它们用于temporal 循环,就像在编程语言中一样(VHDL 是一种硬件描述语言)。如果愿意,循环总是展开的,只是提供了一种更简洁的方式来编写多个相似的语句。在模拟中,您可以像在编程语言中一样通过使用等待语句来使用循环。