--=====================================================
-- Проект 33. Генератор развёртки VGA 640x480@60Гц
-- Из тактовой частоты 25 МГц формирует синхроимпульсы
-- и координаты видимой области.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity vga_sync is
    port (
        clk25   : in  std_logic;                        -- пиксельная частота 25 МГц
        rst     : in  std_logic;
        hsync   : out std_logic;
        vsync   : out std_logic;
        video_on: out std_logic;                        -- в видимой области
        pixel_x : out std_logic_vector(9 downto 0);
        pixel_y : out std_logic_vector(9 downto 0)
    );
end entity vga_sync;

architecture rtl of vga_sync is
    -- горизонталь: 640 видимых + 16 + 96 + 48 = 800
    constant H_VISIBLE : integer := 640;
    constant H_FRONT    : integer := 16;
    constant H_SYNC      : integer := 96;
    constant H_BACK      : integer := 48;
    constant H_TOTAL     : integer := 800;
    -- вертикаль: 480 видимых + 10 + 2 + 33 = 525
    constant V_VISIBLE : integer := 480;
    constant V_FRONT    : integer := 10;
    constant V_SYNC      : integer := 2;
    constant V_TOTAL     : integer := 525;

    signal h_cnt : integer range 0 to H_TOTAL-1 := 0;
    signal v_cnt : integer range 0 to V_TOTAL-1 := 0;
begin
    process (clk25, rst)
    begin
        if rst = '1' then
            h_cnt <= 0;
            v_cnt <= 0;
        elsif rising_edge(clk25) then
            if h_cnt = H_TOTAL - 1 then
                h_cnt <= 0;
                if v_cnt = V_TOTAL - 1 then
                    v_cnt <= 0;
                else
                    v_cnt <= v_cnt + 1;
                end if;
            else
                h_cnt <= h_cnt + 1;
            end if;
        end if;
    end process;

    -- строчный синхроимпульс — активный низкий уровень
    hsync <= '0' when h_cnt >= H_VISIBLE + H_FRONT and
                       h_cnt <  H_VISIBLE + H_FRONT + H_SYNC else '1';
    vsync <= '0' when v_cnt >= V_VISIBLE + V_FRONT and
                       v_cnt <  V_VISIBLE + V_FRONT + V_SYNC else '1';

    video_on <= '1' when h_cnt < H_VISIBLE and v_cnt < V_VISIBLE else '0';
    pixel_x  <= std_logic_vector(to_unsigned(h_cnt, 10));
    pixel_y  <= std_logic_vector(to_unsigned(v_cnt, 10));
end architecture rtl;
