【发布时间】:2019-05-08 09:03:33
【问题描述】:
我应该将来自 ADC 的波形重建到 RAM 中,然后将其发送到 VGA。
我写了这个模块,但是在我合成的时候,vivado报错:[Synth 8-3380] loop condition does not convergence after 2000次迭代。
错误是指while循环,但我不明白原因。不幸的是,如果我不能合成这个模块,我不明白它是否能正常工作。
这是模块:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use ieee.std_logic_arith.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Data_Elab is
Generic (
C: integer := 640; -- Colonne 640
R: integer := 480 -- Righe 480
);
Port (
--clk: in std_logic;
DRP_Data: in std_logic_vector(15 downto 0);
DRP_Ready: in std_logic;
RAM_addr: out std_logic_vector(17 downto 0);
RAM_Data: out std_logic;
RAM_en: out std_logic
);
end Data_Elab;
architecture Behavioral of Data_Elab is
signal data_reg: integer range 0 to 2**16;
--signal flag: std_logic;
begin
process(DRP_Ready, DRP_Data)
begin
if(DRP_Ready'event and DRP_Ready = '1') then
data_reg <= to_integer(unsigned(DRP_Data));
end if;
end process;
process(data_reg)
variable Cont_W: integer range 0 to C-1 := 0; -- contatore per spostamento tra colonne
variable Cont_i: integer range 0 to C := 1; -- contatore colonne
variable Cont_x: integer range 0 to R := 1; -- contaore per spostamento tra righe
variable Cont_R: integer range 0 to R := 0; -- contatore righe
begin
if(Cont_i <= C) then
if( data_reg <= (2**16/R)*Cont_x ) then
RAM_addr <= std_logic_vector(to_unsigned( (C*(R-Cont_x))+Cont_W, RAM_addr'length));
RAM_en<= '1';
RAM_Data <= '1'; -- pixel corrispondente alla forma d'onda (bianchi)
Cont_W := Cont_W+1;
Cont_i := Cont_i+1;
--Cont_R := Cont_R+1;
--Cont_x := 1;
while Cont_R < R loop
RAM_addr <= std_logic_vector(to_unsigned( (C*(R-Cont_x))+Cont_W, RAM_addr'length));
RAM_en<= '1';
RAM_Data <= '0'; -- pixel neri
Cont_R := Cont_R+1;
Cont_x:= Cont_x+1;
end loop;
Cont_R := 0;
else
RAM_addr <= std_logic_vector(to_unsigned( (C*(R-Cont_x))+Cont_W, RAM_addr'length));
RAM_en<= '1';
RAM_Data <= '0'; -- pixel neri
Cont_R := Cont_R+1;
Cont_x:= Cont_x+1;
end if;
else
RAM_en<= '0';
Cont_W := 0;
Cont_i := 1;
Cont_x := 1;
Cont_R := 0;
end if;
end process;
end Behavioral;
模块尝试将完整的图像从 640*480 像素写入 RAM 块中,这样我可以稍后读取存储在 RAM 中的值并将它们发送到 VGA 模块。
谢谢。
【问题讨论】:
-
您有一些来自 ADC 的数据。一次一个样品。这会消耗一些时间。然而,您已经注释掉了
clk输入,并试图用组合逻辑来实现它。您需要将 VHDL 放下一段时间,然后使用铅笔和纸来设计电路以实现您需要的行为(不是在门级,而是在块级*)。完成后,返回 VHDL 并实现它。该电路必须是顺序的;也就是说,它必须使用您的clk输入,并且需要触发器。 -
*“块级别”是什么意思?我的意思是用移位寄存器、状态机、计数器、触发器、组合逻辑云等绘制图表。I mean this kind of thing - 这不是解决方案 - 这是我所说的块级的一个例子。跨度>
-
感谢您的回答。@user1155120,您是对的,但我想自己找到解决世代问题的解决方案,并随后将图像保存在 RAM 上。我正在使用 ZYBO 7000 板。我的想法是使用 Xilin XADC,在 UG480 指南(第 73 页)中指定了如何将它用于我的案例。 DRP_Ready 信号来自 ADC,当 ADC 在其寄存器上准备好数据时,它为高电平。
-
我的代码尝试写入所有 RAM,这样我就可以在 VGA 模块上读取并发送整个图像(我已经完成并成功测试)。我在纸上进行了尝试(为简单起见,使用仅 4 * 4 像素的图像作为测试),在我看来它运行良好。虽然我肯定必须调整时序,因为 ADC 每 26 个 clk 周期(clk 为 25MHz)提供一个新数据,并且每个数据的计算时间可能会更长。但是,如果 while 循环不可合成,我将不得不完全修改该块。