【问题标题】:ADC to RAM signal reconstruction (after send it to VGA)ADC 到 RAM 信号重建(发送到 VGA 后)
【发布时间】: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 循环不可合成,我将不得不完全修改该块。

标签: vhdl ram adc vga


【解决方案1】:

我猜合成器不够聪明,无法知道 while 循环会运行多少次,因为它在每个循环中都会发生变化。我建议改用 for 循环。

for Cont_R in 0 to R-1 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_x:= Cont_x+1;    
end loop;

【讨论】:

  • 感谢您的回复。但是我需要循环使用当时的 Cont_R 值。例如:for Cont_R in Cont_R to R-1 loop 但这会产生另一个错误 [Synth 8-561] range expression could not be resolved to a constant
猜你喜欢
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多