0

我一直在疯狂地试图让它工作,但在过去的 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;

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

4

2 回答 2

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 的垂直同步率:

sync_vga_tb_full.png

在两个 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 的回答:

时钟_tb.png

你除以二实际上除以四。给出一个 80 ns (12.5 MHz) 的周期。

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

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

于 2016-02-20T21:37:44.067 回答
0

从以下问题的评论中:

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

您的时钟分频器将输入频率除以 4 而不是 2。您TEMP每两个周期切换一次,CLK其中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',它在 的第一个上升沿切换为“1” CLK。在第二个上升沿TEMP切换到“0”,在第三个上升沿切换回“1”。50 MHz 输入时钟的第一个和第三个上升沿之间的持续时间为 40 ns,这使得输出时钟的频率为 25 MHz。

于 2016-02-20T19:43:58.560 回答