刷新时VGA VHDL屏幕会移动

刷新时VGA VHDL屏幕会移动,vhdl,vga,Vhdl,Vga,我正试图用这个VHDL在屏幕上创建一个网格。 我现在可以做两行,但是当我刷新屏幕时,行会移动。 我不确定错误在哪里,有人能帮忙或提供一些建议吗 library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_unsigned.all; --use IEEE.std_logic_arith.all; --VVVVVVV use IEEE.NUMERIC_STD.all;

我正试图用这个VHDL在屏幕上创建一个网格。 我现在可以做两行,但是当我刷新屏幕时,行会移动。 我不确定错误在哪里,有人能帮忙或提供一些建议吗

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_unsigned.all;
--use IEEE.std_logic_arith.all; --VVVVVVV
use IEEE.NUMERIC_STD.all;       --^^^^^^^ 

entity SCRN is
port(
    clk     : in STD_LOGIC;
    vga     : OUT STD_LOGIC_VECTOR (7 downto 0);
    Hsync : OUT STD_LOGIC;
    Vsync : OUT STD_LOGIC
    );
end SCRN;

architecture Behavioral of SCRN is

type PLC_HOLD is array (1 to 800, 1 to 525) of STD_LOGIC_VECTOR(7 downto 0);
signal scrn : PLC_HOLD;

signal s_clk    : std_logic_vector (1 downto 0) := (others => '0');
signal xx_vga   : std_logic_vector (7 downto 0);

signal xx_h : std_logic;
signal xx_v : std_logic;

signal X : std_logic_vector (9 downto 0) := (others => '1');
signal Y : std_logic_vector (9 downto 0) := (others => '1');

-- signal test : ieee.numeric_std.unsigned 
-- test now works with mod
begin

NW_CLK: process (clk) is
    begin
    if rising_edge (clk) then 
        s_clk <= (s_clk + "01");
    end if;
end process NW_CLK;
--###############################--
scrn_loc : 
process (s_clk(1)) is

begin
    if RISING_EDGE (s_clk(1)) then
    X <= X + "0000000001";
        if (X = "1100100000") then --if x = 800
            X <= "0000000001"; 
            Y <= (Y + "0000000001");
        elsif (Y = 525) then -- if y = 525
            X <= "0000000001"; 
            Y <= "0000000001";
        end if;
    end if;
end process;

--###############################--
draw : 
process (X,Y) is 

    -- h and v sync process
    begin
    if (X > 640) then -- and (X <= 752) then -- low for sync pulse at 656 to 752 -- 96 pixel
        xx_h <= '0';
    else 
        xx_h <= '1';
    end if;

    if (Y> 490) and (Y <= 492) then -- low for sync puls at 490 to 492
        xx_v <= '0';
    else
        xx_v <= '1';
    end if;
--  (CONV_INTEGER((X)) mod 10)
-- CONV_INTEGER(Y) mod 10
--  if  X = 1 then
--      xx_vga <= "00111000";
----    elsif Y = 1 or Y = 480 then
----        xx_vga <= "11101011";
--  else 
--      xx_vga <= "11100000";
--  end if;

end process;
--###############################--


scrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <=    "00111000" when X = 1 else
                                                "11100101" when Y = 2 else
                                                "00000111" when X = 640 else
                                                "11001101";

Hsync <= xx_h;
Vsync <= xx_v;

vga <= scrn(CONV_INTEGER(X),CONV_INTEGER(Y));

end Behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.all;
使用IEEE.std_logic_unsigned.all;
使用IEEE.std_logic_unsigned.all;
--使用IEEE.std_logic_arith.all--VVVV
使用IEEE.NUMERIC_STD.all;--^^^^
实体SCRN是
港口(
clk:标准逻辑中;
vga:输出标准逻辑向量(7到0);
Hsync:输出标准逻辑;
输出标准逻辑
);
结束SCRN;
SCRN的体系结构是
PLC保持型是标准逻辑向量(7到0)的阵列(1到800,1到525);
信号scrn:PLC保持;
信号s_clk:std_逻辑_向量(1到0):=(其他=>'0');
信号xx_vga:std_逻辑_矢量(7到0);
信号xx_h:std_逻辑;
信号xx_v:标准_逻辑;
信号X:std_逻辑_向量(9到0):=(其他=>'1');
信号Y:std_逻辑_向量(9到0):=(其他=>'1');
--信号测试:ieee.numeric\U std.无符号
--测试现在与mod一起工作
开始
西北时钟:进程(时钟)为
开始
如果上升沿(clk),则

s_clkHmmm。。。如果将指定给scrn(CONV_INTEGER(X)、CONV_INTEGER(Y))的行移动到
scrn时会发生什么情况?这是一个坏主意。你好像想除以4?而是创建一个启用脉冲:

NW_CLK: process (clk) is
  variable divider : integer range 0 to 3;
    begin
    if rising_edge (clk) then 
        if divider = 3 then
           divider := 0;
           screen_process_enable <= '1';
        else
           divider := divider + 1;
           screen_process_enable <= '0';
        end if
    end if;
end process NW_CLK;

与您的问题无关,但我将在这里对此进行评论:您似乎试图将整个屏幕保存在内存中-这是您在实际芯片中要求的相当多的存储空间(在模拟中可以)


要生成网格,您只需根据x和y计数器的值分配VGA输出即可。由于您在一个进程之外同时拥有
scrn
vga
的分配,因此合成器可能足够聪明,可以发现您从未使用过所需的内存存储,并且已经对其进行了优化。如果在将来的某个时候,您使用
scrn
作为真正的帧缓冲区,您可能会遇到性能或资源限制,具体取决于您的设备。

查看“使用VHDL进行电路设计和模拟”的第15章(VGA视频接口的VHDL设计),这显示了详细的VGA理论,随后使用VHDL和VGA监视器进行了大量实验。

我认为这只能在VHDL 2012中完成,或者以最新版本为准。不幸的是,Xilinx不支持最新版本,所以我不能这么做。你确定吗?因为这些仍然是标准逻辑向量,有9个可能的值。也许如果我让它们成为位向量…?关于数值:只使用整数。它们与Xilinx的工具配合使用,将使您的生活更加轻松。请删除std_logic_unsigned的两个副本!您是否尝试使用赋值
scrn(CONV_INTEGER(X),CONV_INTEGER(Y))移动该行
scrn_loc : process (clk) is

begin
    if RISING_EDGE (clk) and screen_process_enable = '1' then
       etc...