【问题标题】:Why my VHDL code for generating a VGA signal doesn't work为什么我用于生成 VGA 信号的 VHDL 代码不起作用
【发布时间】:2016-02-20 16:41:54
【问题描述】:

我一直在努力让它工作,但在过去的 6 个小时里没有任何事情发生并且仍然没有解决它:/

所以这是顶级模块

library IEEE;
use IEEE.STD_LOGIC_1164.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 primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Test is
  Port ( CLKI : in  STD_LOGIC;
         HSO : out  STD_LOGIC;
         VSO : out  STD_LOGIC;
         RO,GO,BO : out  STD_LOGIC);
end Test;

architecture Behavioral of Test is
  component CLK_25Mhz_Divider
    Port ( CLK : in  STD_LOGIC;
           CLK_OUT : out  STD_LOGIC);
  end component;

  component VGA_Sync
    Port ( CLK : in  STD_LOGIC;
           HS : out  STD_LOGIC;
           VS : out  STD_LOGIC;
           R,G,B : out  STD_LOGIC);
  end component;

  signal CLKBE: STD_LOGIC;

begin

  CLK_Divider_1: CLK_25Mhz_Divider port map ( CLK => CLKI,
                                              CLK_OUT => CLKBE);

  VGA_S1: VGA_Sync port map ( CLK => CLKBE,
           HS => HSO,
           VS => VSO,
           R  => RO,
              G  => GO,
              B  => BO );

end Behavioral;

时钟分频器

library IEEE;
use IEEE.STD_LOGIC_1164.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 primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity CLK_25MHz_Divider is
    Port ( CLK : in  STD_LOGIC;
           CLK_OUT : out  STD_LOGIC);
end CLK_25MHz_Divider;

architecture Behavioral of CLK_25MHz_Divider is

 BEGIN
     PROCESS(CLK)
          VARIABLE COUNT : INTEGER:=0;
          VARIABLE TEMP : STD_LOGIC:='0';
          BEGIN
                IF RISING_EDGE(CLK)THEN
                     COUNT:=COUNT+1;
                     IF COUNT=2 THEN
                          TEMP:=NOT TEMP;
                          COUNT:=0;
                     END IF;
                END IF;
                CLK_OUT<=TEMP;
                END PROCESS;
end Behavioral;

VGA信号产生模块

library IEEE;
use IEEE.STD_LOGIC_1164.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 primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity VGA_Sync is
    Port ( CLK : in  STD_LOGIC;
           HS : out  STD_LOGIC;
           VS : out  STD_LOGIC;
           R,G,B : out STD_LOGIC);
end VGA_Sync;

architecture Behavioral of VGA_Sync is

begin 

  process(CLK)

  Variable countH : Integer := 0;
  Variable countV : Integer := 0;

    begin
     if (CLK'EVENT and CLK = '1') then

        if countH < 800 then 
            countH := countH + 1;
        else 
            countH := 0;
           if countV < 500 then
                countV := countV + 1;
        else 
               countV := 0;
           end if;
        end if;

        if countH >= 16 and countH < 112 then
           HS <= '0';
       else 
           HS <= '1';
        end if;

        if countV >= 10 and countV < 12 then
           VS <= '0';
       else 
           VS <= '1';
        end if;

        if (countH < 160) or (countV < 45) then 
           R <= '0';
            G <= '0';
            B <= '0';
        else 
           R <= '1';
            G <= '0';
            B <= '1';
      end if;
   end if;
 end process;       
end Behavioral;

所以告诉我你对代码有什么问题的想法

【问题讨论】:

  • 顺便说一句,我的目标是640x480
  • 请清理您的问题。您已经发布了两次vga_sync。缺少顶级组件和测试平台。什么是错误(消息)?并删除不必要的注释行。
  • 很抱歉发布 vga_sync 两次,我现在已修复。不是我收到错误,我的代码没有给我任何语法错误,但是当我将板连接到屏幕时,当像素的颜色应该变为洋红色时,什么都没有显示。我已经做了一个测试台,但这里不值得写,因为它只是一个时钟并且测试台没有显示任何错误,如果你愿意,我可以将它包含在波形的一些屏幕截图中。
  • CLKI的频率是多少?这就是我要求测试平台的原因。
  • 在那个分辨率下,我应该使用 25Mhz,所以我使用 50 Mhz 的板载时钟并使用时钟分频器模块对其进行分频。

标签: vhdl clock xilinx vga spartan


【解决方案1】:

因为您实际上没有描述问题,并且因为我有一个 25 MHz 时钟 vga 发生器的测试台,只需要更改 r、g 和 b 的类型,所以我针对测试台运行了 sync_vga:

library ieee;
use ieee.std_logic_1164.all;

entity vga_sync_tb is
end entity;

architecture foo of vga_sync_tb is
    signal clk:    std_logic := '0';
    signal hs:     std_logic;
    signal vs:     std_logic;
    signal r,g,b:  std_logic;
begin
DUT:
    entity work.vga_sync 
        port map (
            clk => clk,
            hs => hs,
            vs => vs,
            r => r,
            g => g,
            b => b
        );
CLOCK:
    process
    begin
        wait for 20 ns;  -- clock period 25 MHz = 40 ns;
        clk <= not clk;
        if now > 20 ms then  -- one frame time plus a bit
            wait;
        end if;
    end process;
end architecture;

它给出了大约 60 Hz 的垂直同步率:

在两个 HS 边缘之间放大和测量显示水平速率约为 31.17 KHz。

您有水平和垂直消隐间隔,您的 R、G 和 B 会按照您的代码执行。

那种离开时钟分频器或与平台相关的东西。

因为时钟的测试台很简单:

library ieee;
use ieee.std_logic_1164.all;

entity clock_tb is
end entity;

architecture foo of clock_tb is
    signal clk:     std_logic := '0';
    signal clk25:   std_logic;
begin
DUT:
    entity work.clk_25mhz_divider
        port map (
            clk => clk,
            clk_out => clk25
        );
CLOCK:
    process
    begin
        wait for 10 ns; -- half the period of 50 MHz
        clk <= not clk;
        if now > 130 ns then
            wait;
        end if;
    end process;
end architecture;

它展示了 Martin Zabel 的回答:

你的除以二实际上除以四。周期为 80 ns (12.5 MHz)。

这证明了模拟的有用性,并且在模拟中使用信号而不是没有历史的变量也很有帮助。变量没有投影的输出波形,模拟器必须附加额外的代码才能在波形中显示它们。

使用变量而不是信号来提高模拟性能是为了显示它们的能力,并且在合成中没有有趣的区别。

【讨论】:

  • 感谢您的解释。这是我将来会记住的事情。我不精通 VHDL,因为我不经常使用它,但我已经掌握了它。
  • @Mostafa :如果您从这个出色的答案中学到一件事,那就这样吧:编写测试台并模拟您的设计不需要六个小时。
  • 我不得不承认,这个答案比我的要好,因为它演示了子模块测试。所以,+1。太糟糕了,我应该知道的。
【解决方案2】:

来自以下问题的cmets:

在那个分辨率下,我应该使用 25Mhz,所以我使用板载时钟 那是 50 Mhz 并使用时钟分频器模块对其进行分频。 – 穆斯塔法

您的时钟分频器将输入频率除以 4 而不是 2。您每两个周期切换一次 TEMPCLK,即顶部模块的 CLKI。所以CLK_OUT 的一个完整周期需要输入时钟的 4 个周期。

要除以二,必须在输入时钟的每个时钟周期切换TEMP

architecture Behavioral of CLK_25MHz_Divider is
BEGIN
     PROCESS(CLK)
          VARIABLE TEMP : STD_LOGIC:='0';
     BEGIN
         IF RISING_EDGE(CLK)THEN
             TEMP:=NOT TEMP;
         END IF;
         CLK_OUT<=TEMP;
     END PROCESS;

end Behavioral;

TEMP = '0' 开始,它在CLK 的第一个上升沿切换为“1”。在第二个上升沿,TEMP 切换为“0”,并在第三个上升沿返回“1”。 50 MHz 输入时钟的第一个和第三个上升沿之间的持续时间为 40 ns,这使得输出时钟的频率为 25 MHz。

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多