Я использую Basis3 FPGA, и у меня есть генератор тестовых шаблонов, который отображает набор изображений на мониторе. Проблема в том, что каждое изображение «сбито», что означает, что первый пиксель в каждой горизонтальной линии является пикселем из предыдущей строки. Например, если бы у меня был черный белый & белый экран, а верхняя половина - белая, а нижняя половина - черная, первый пиксель в первой черной линии был бы белым. В принципе, похоже, что весь первый вертикальный столбец сдвинут вниз на один пиксель.VHDL: Как отменить сигналы VGA?
Из-за того, что мне сказал мой профессор, проблема связана с тем, что сигналы (h_sync, v_sync, RGB) не синхронизированы, h_sync и v_sync впереди с 1 бит из-за задержки сигналы RGB, когда я делаю выбор изображений. Под выбором я имею в виду, что у меня есть 4 активных переключателя, которые (в зависимости от состояния включения/выключения) выбирают изображения в двоичном виде. (Пример: 4 переключателей в 0101 состоянии, то отображается пятое изображение 0011 состояния, третье изображение, отображаемым и так далее.).
Это код для выбора:
type Colors is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0);
signal redArr : Colors;
signal greenArr : Colors;
signal blueArr : Colors;
process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if flagAV = '1' then
RED <= redArr (conv_integer (SW));
GREEN <= greenArr (conv_integer (SW));
BLUE <= blueArr (conv_integer (SW));
else
RED <= "00000000";
GREEN <= "00000000";
BLUE <= "00000000";
end if;
LED <= SW;
end if;
end process;
Массива (Цвета) имеет 16 элементов, потому что у меня 16 изображений, поэтому 4 переключателя (SW) достаточно, чтобы отобразить их все. Я использовал 8 бит на цвет. flagAV
- это просто проверить, являюсь ли я активной областью или нет.
У меня есть отдельный модуль (VGADraw) для этого выбора изображений, а другой (VGADrive), где я определяю H/V sync, H/V пустые сигналы. Затем счетчики строятся в модуле выбора изображения, используя пустые сигналы H/V от VGADrive.
Н/V SYNC и пустые сигналы, определенные в VGADrive:
HorizontalSync: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (inCntHor = RES.cstHorFP + RES.cstHorAL - 1) then
inHS <= '0';
elsif (inCntHor = RES.cstHorFP + RES.cstHorAL + RES.cstHorPW - 1) then
inHS <= '1';
end if;
end if;
end process;
HorizontalBlanking: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (inCntHor = RES.cstHorAL - 1) then
inHBL <= '1';
elsif (inCntHor = RES.cstHorTotSize - 1) then
inHBL <= '0';
end if;
end if;
end process;
VerticalSync: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (inCntVer = RES.cstVerFP + RES.cstVerAL - 1) then
inVS <= '0';
elsif (inCntVer < RES.cstVerFP + RES.cstVerAL + RES.cstVerPW - 1) then
inVS <= '1';
end if;
end if;
end process;
VerticalBlanking: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (inCntVer = RES.cstVerAL - 1) then
inVBL <= '1';
elsif (inCntVer = RES.cstVerTotSize - 1) then
inVBL <= '0';
end if;
end if;
end process;
Счетчики, построенные в модуле выбора изображений (VGADraw) с использованием гашения сигналов:
VerticalCounter: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
HBLold <= HBL;
if HBL = '0' and HBLold = '1' then
if VBL = '1' then
incntVer <= 0;
else
incntVer <= incntVer + 1;
end if;
end if;
end if;
end process;
HorizontalCounter: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
if HBL = '1' then
incntHor <= 0;
else
incntHor <= incntHor + 1;
end if;
end if;
end process;
cstHorAL - пиксели/активные линии
cstHorFP - пикселы/переднее крыльцо
cstHorPW - PIXE Ls/ширина импульса
cstHorBP - пиксели/назад крыльцо
cstHorTotSize - пикселей/общее количество линий
cstVerAL - линии/активные линии
cstVerFP - линии/передний крыльцо
cstVerPW - линии/ширина импульса
cstVerBP - линии/задние крыльцо
cstVerTotSize - линии/общее количество кадров
HBLold - используется для падения края обнаружения
Мой вопрос, как я задержать h_sync и v_sync сигналы от этого 1 бит, так что изображения отображаются правильно без тех, первые пиксели сдвинуты, и в каком модуле я это делаю?
Вы задаете вопрос о сигналах, которые не отображаются в опубликованном коде. Поэтому вы можете только ожидать смутного ответа; которые будут: просто назначьте их в тактированном процессе, как указано выше. (Ох и используйте функцию 'rising_edge' вместо того, чтобы возиться с атрибутами события низкого уровня). –
По правде говоря, я не знал, какую часть кода отправлять, полный код будет слишком большим. Но я добавлю последовательности, где я определяю сигналы синхронизации, пустые и встречные сигналы. –
Думаю, я реализовал это, как вы сказали, и «искажение», похоже, стало меньше. Но все еще есть тонкий столкновение. Что-нибудь еще, что я мог сделать? Я попытался отложить его еще с помощью 'after', но никакого эффекта. –