AFON // радиотехник affonya@mail.ru
← Проекты на VHDL

Проект 28. Развёртка VGA 640×480

Два счётчика формируют строчную и кадровую синхронизацию по стандартным таймингам и выдают текущие координаты пикселя. Это основа любого вывода изображения с ПЛИС.

Задача

Сформировать сигналы синхронизации для монитора VGA.

Тип схемы: Синхронная схема из двух счётчиков с пиксельной частотой 25 МГц.
Модуль: vga_sync. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования. Теорию по языку смотрите в статье VHDL — язык описания аппаратуры, по самим микросхемам — на странице ПЛИС.

Алгоритм

  1. Считать пиксели в строке до полной длины строки с учётом гасящих интервалов.
  2. По окончании строки увеличивать счётчик строк кадра.
  3. Формировать импульсы синхронизации в заданных диапазонах счётчиков.
  4. Выдавать признак активной области и текущие координаты.

Код на VHDL

Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v28.vhd

--=====================================================
-- Проект 28. Развёртка VGA 640x480
-- Формирование строчной и кадровой синхронизации
-- по стандартным таймингам при пикселной частоте 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;                       -- активная область экрана
        px      : out std_logic_vector(9 downto 0);     -- координата X
        py      : out std_logic_vector(9 downto 0)      -- координата Y
    );
end entity vga_sync;

architecture rtl of vga_sync is
    -- стандартные тайминги режима 640x480 при 60 Гц
    constant H_VISIBLE : integer := 640;
    constant H_FRONT   : integer := 16;
    constant H_SYNC    : integer := 96;
    constant H_TOTAL   : integer := 800;
    constant V_VISIBLE : integer := 480;
    constant V_FRONT   : integer := 10;
    constant V_SYNC    : integer := 2;
    constant V_TOTAL   : integer := 525;

    signal hcnt : integer range 0 to H_TOTAL-1 := 0;
    signal vcnt : integer range 0 to V_TOTAL-1 := 0;
begin
    process (clk25, rst)
    begin
        if rst = '1' then
            hcnt <= 0; vcnt <= 0;
        elsif rising_edge(clk25) then
            if hcnt = H_TOTAL-1 then                    -- конец строки
                hcnt <= 0;
                if vcnt = V_TOTAL-1 then                -- конец кадра
                    vcnt <= 0;
                else
                    vcnt <= vcnt + 1;
                end if;
            else
                hcnt <= hcnt + 1;
            end if;
        end if;
    end process;

    -- импульсы синхронизации активны низким уровнем
    hsync <= '0' when (hcnt >= H_VISIBLE + H_FRONT) and
                      (hcnt <  H_VISIBLE + H_FRONT + H_SYNC) else '1';
    vsync <= '0' when (vcnt >= V_VISIBLE + V_FRONT) and
                      (vcnt <  V_VISIBLE + V_FRONT + V_SYNC) else '1';

    video_on <= '1' when hcnt < H_VISIBLE and vcnt < V_VISIBLE else '0';
    px <= std_logic_vector(to_unsigned(hcnt, 10));
    py <= std_logic_vector(to_unsigned(vcnt, 10));
end architecture rtl;

Пояснения

  • Полная строка длиннее видимой части: помимо 640 пикселей в неё входят передний портал, импульс синхронизации и задний портал — всего 800 тактов.
  • Импульсы синхронизации в этом режиме активны низким уровнем — их полярность строго задана стандартом.
  • Пиксельная частота 25 МГц получается делением стандартных 50 МГц пополам, что удобно для типовых отладочных плат.

Что дальше

Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.