Задача
Сформировать сигналы синхронизации и координаты для видеовыхода VGA.
Тип схемы: Синхронная схема: два счётчика и комбинационная логика сравнения.
Модуль: vga_sync. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования.
Теорию по языку смотрите в статье VHDL — язык описания аппаратуры,
по самим микросхемам — на странице ПЛИС.
Алгоритм
- Считать пиксели в строке до полного горизонтального периода.
- По окончании строки увеличивать счётчик строк.
- Формировать синхроимпульсы в заданных интервалах каждого периода.
- Выдавать признак видимой области и текущие координаты.
Код на VHDL
Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v33.vhd
--=====================================================
-- Проект 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;
Пояснения
- Стандарт VGA задаёт не только видимую область, но и служебные интервалы (передний фронт, синхроимпульс, задний фронт) — без них монитор не поймает кадр.
- Синхроимпульсы для этого режима активны низким уровнем — это нужно свериться в документации на конкретный монитор.
- Пиксельная частота 25 МГц обычно получается из основного тактового генератора платы делителем или блоком ФАПЧ (PLL) кристалла.
Что дальше
Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.