我正在尝试使用此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;
嗯...如果将分配给scrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <= "00111000" when X = 1 else ...
的行移动到流程中的某个位置,会发生什么情况?
此外,无需在代码中使用二进制文字(例如,if (X = "1100100000")
)。只需使用整数文本或十进制位字符串文本。更好的是,将所有数值定义为整数或自然值。作为奖励,您的代码会更干净,因为您不需要所有这些转换函数。
您正在从时钟创建时钟,这是一个坏主意。 看来你想除以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;
然后在筛选过程中:
scrn_loc : process (clk) is
begin
if RISING_EDGE (clk) and screen_process_enable = '1' then
etc...
与您的问题无关,但无论如何我都会在这里发表评论:您似乎试图将整个屏幕保存在内存中 - 这是您在真实芯片中要求的相当多的存储空间(在模拟中会很好)。
要生成网格,您可以根据x和y计数器的值分配给VGA输出,从而即时完成。 因为你既有要scrn
的任务,又有进程之外的vga
,所以合成器可能足够聪明,可以发现你从来没有利用你要求的内存存储,并优化了它。如果在将来的某个时候,您将scrn
用作真正的帧缓冲,则可能会遇到性能或资源限制,具体取决于您的设备。
查看"使用VHDL进行电路设计和仿真"的第15章(VGA视频接口的VHDL设计),其中显示了详细的VGA理论,然后是使用VHDL和VGA监视器进行的一些实验。