Skocz do zawartości

Przesunięty obraz na monitorze VGA


Pomocna odpowiedź

Napisano

W ramach zabawy płytką Elbertv2 postanowiłem spróbować coś wyświetlić na monitorze VGA. Bazowałem na blogu, którego link jest na stronie producenta płytki: https://langster1980.blogspot.co.uk/2015/08/driving-vga-port-using-elbert-v2-and_7.html

Okazało się, że instrukcja jest mocno niekompletna, ale w końcu udało mi się uzyskać obraz na ekranie.

Trochę się czepiam, ale efekt był przesunięty o jedną linię i mam wrażenie, że autor nie do końca rozumiał problem, więc po prostu pierwszą linię pomijał.

if (hcounter >= 1) and (hcounter < 480) and (vcounter >= 1) and (vcounter < 640 ) 
      then pixels <= x"F0"; 
   -- If the condition is not satisfied then the output colour will be black. 
   else 
    pixels <= x"00"; 
   end if; 

Wygląda na to że oryginalny kod pochodzi ze strony: https://github.com/numato/samplecode/blob/master/FPGA/ExpansionModules/VGA8bit/src/spartan3/VGAExpansionModule.vhd

Próbowałem zrozumieć różnice i wydaje mi się, że problem wynika z użycia (lub nie) zmiennych nextVCount i nextHCount.

W oryginalnym kodzie kolor był obliczany na podstawie kolejnego piksela, co jest chyba sensowne, ponieważ wynik będzie dostępny w kolejnym cyklu zegara.

Napisałem własną wersję programu, gdzie starałem się uprościć użycie zmiennych next - żeby uniknąć dodawania dla obu par zmiennych:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity vga_sync is port(
clk : in std_logic;
hsync : out std_logic;
vsync : out std_logic;
red : out std_logic_vector(2 downto 0);
green : out std_logic_vector(2 downto 0);
blue : out std_logic_vector(2 downto 1)
);	
end vga_sync;

architecture Behavioral of VGA_sync is

signal hcount : integer range 0 to 1023;
signal vcount : integer range 0 to 1023;
signal next_hcount : integer range 0 to 1023;
signal next_vcount : integer range 0 to 1023;
signal rgb : std_logic_vector(7 downto 0);

begin

vga_signal: process (clk) is
begin
if rising_edge(clk) then
	if (next_hcount = 799) then
		next_hcount <= 0;
		if (next_vcount = 525) then
			next_vcount <= 0;
		else
			next_vcount <= next_vcount + 1;
		end if;
	else
		next_hcount <= next_hcount + 1;
	end if;

	if (vcount >= 490) and (vcount < 492) then
		vsync <= '0';
	else
		vsync <= '1';
	end if;

	if (hcount >= 656) and (hcount < 752) then
		hsync <= '0';
	else
		hsync <= '1';
	end if;

	hcount <= next_hcount;
	vcount <= next_vcount;
end if;	
end process;

display: entity VGA_display port map (clk => clk, x => next_hcount, y => next_vcount, color => rgb);

red <= rgb(7 downto 5);
green <= rgb(4 downto 2);
blue <= rgb(1 downto 0);

end Behavioral;

Komponent VGA_display ma taki kod:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity vga_display is port(
clk : in std_logic;
x : in integer range 0 to 1023;
y : in integer range 0 to 1023;
color : out std_logic_vector(7 downto 0)
);
end vga_display;

architecture Behavioral of vga_display is
begin

process (clk) is
begin
if rising_edge(clk) then
	if (x < 640) and (y < 480) then
		if (x = 0) or (x = 639) or (y = 0) or (y = 479) then
			color <= x"ff";			
		else
			if (y < 160) then
				color <= x"e0";
			elsif (y < 320) then
				color <= x"1c";
			else
				color <= x"03";
			end if;
		end if;
	else
		color <= x"00";
	end if;
end if;
end process;

end Behavioral;

Chodziło mi o narysowanie ramki dookoła ekranu i sprawdzenie, czy tym razem obraz wyświetlany jest prawidłowo. Jest lepiej niż kod z bloga, ale niestety nadal nie idealnie:

Na tym monitorze obcięta jest górna linia. Podłączałem Elbert-a do normalnego monitora i wtedy dla odmiany niewidoczna była linia najbardziej po lewej stronie.

Wydaje mi się, że coś jest nie tak z timing-ami, ale nie mam już pomysłów. Stąd moje pytanie, jak poprawić ten kod i uzyskać poprawny obraz?

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...