ho visto pubblicati alcuni sorgenti in vhdl e volevo contribuire anche io visto che mi sono
messo al''opera per realizzare un controller video vga da interfacciare ad un micro.
Ho preso spunto da alcuni documenti di qualche anno fa di deluca relativi alla generazione dei segnali VGA.
Io sto iniziando strutturando l'interfaccia in questo modo
1) modulo VGA
2) contatore per righe e colonne
3) interfaccia rom contenente le informazioni dei pixel
Intanto rilascio il codice per il modulo VGA sperando che qualcuno possa valutare ed eventualmente
fare qualche appunto per ottimizzare il codice.
- Code: Select all
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- clk = 25.275 MHz
-----------------------------------------------------------------------------------
entity controllo_vga is
Port ( clk : in STD_LOGIC;
hsync : out STD_LOGIC;
vsync : out STD_LOGIC;
v_blank: out std_logic;
h_blank: out std_logic;
en_clk :out STD_LOGIC);
end controllo_vga;
------------------------------------------------------------------------------------
architecture Behavioral of controllo_vga is
constant max_x : integer := 799; -- 799 risoluzione orizzontale
constant max_y : integer := 525; -- 525 risoluzione verticale
signal h_counter: integer range 0 to max_x; -- contatore orizzontale
signal v_counter: integer range 0 to max_y; -- contatore verticale
signal fineriga: std_logic;
signal enable_h: std_logic;
signal enable_v: std_logic;
begin
-- primo contatore per sincronismo orizzontale da 0 a 799
H_contatore:process(clk)
begin
if rising_edge(clk) then
if h_counter = max_x then
h_counter <= 0;
fineriga <='1';
else
h_counter <= h_counter + 1;
fineriga <='0'; -- reset fineriga
end if;
else null;
end if;
end process;
-- secondo contatore per sincronismo verticale da 0 a 525
V_contatore:process(clk,fineriga)
begin
if rising_edge(clk) then
if fineriga='1' then
if v_counter = max_y then
v_counter <= 0;
else
v_counter <= v_counter + 1;
end if;
else null;
end if;
else null;
end if;
end process;
-- processo per generare impulso sincronismo verticale e orizzontale
process (h_counter,v_counter,enable_h,enable_v) -- solo contatore verticale e orizzontale
begin
-- Generazione sincronismo orizzontale
if (h_counter>0 and h_counter <96) then -- qui genera impulso Hsync tra 1 e 96
hsync<='0';
else
hsync<='1';
end if;
-- Generazione sincronismo verticale
if (v_counter>0 and v_counter <3) then -- qui genera impulso Vsync tra 1 e 2
vsync <='0';
else
vsync <='1';
end if;
-- Segnale enable counter orizzontale 600 pixel
-- 0 599
if (h_counter >=152) and (h_counter<=751) then -- (160,759) qui creo un enable counter orizzontale
enable_h<='1'; -- per visualizzare pixel (zona display H)
else -- 600 pixel
enable_h<='0';
end if;
-- Segnale enable counter orizzontale 600 pixel
-- 0 599
if (h_counter >=152) and (h_counter<=751) then -- enable counter orizzontale
h_blank<='1';
else -- 600 pixel
h_blank<='0';
end if;
-- Segnale di blank verticale e di enable counter verticale
-- 0 399
if (v_counter>=70) and (v_counter<=469) THEN -- (71, 470) qui creo un enable counter verticale
enable_v<='1'; -- per visualizzare pixel (zona display V)
v_blank<='1';
else
enable_v<='0';
v_blank<='0'; -- qui posso scrivere sulla ram
end if;
-- Segnale uscita Enable clock
IF (enable_h='1') and (enable_v='1') then -- qui mi creo un enable display
--per il verticale e orizzontale
en_clk <='1';
else
en_clk <='0';
end if;
end process;
end Behavioral;