2016-06-16 3 views
0

Я использую 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 бит, так что изображения отображаются правильно без тех, первые пиксели сдвинуты, и в каком модуле я это делаю?

+2

Вы задаете вопрос о сигналах, которые не отображаются в опубликованном коде. Поэтому вы можете только ожидать смутного ответа; которые будут: просто назначьте их в тактированном процессе, как указано выше. (Ох и используйте функцию 'rising_edge' вместо того, чтобы возиться с атрибутами события низкого уровня). –

+0

По правде говоря, я не знал, какую часть кода отправлять, полный код будет слишком большим. Но я добавлю последовательности, где я определяю сигналы синхронизации, пустые и встречные сигналы. –

+0

Думаю, я реализовал это, как вы сказали, и «искажение», похоже, стало меньше. Но все еще есть тонкий столкновение. Что-нибудь еще, что я мог сделать? Я попытался отложить его еще с помощью 'after', но никакого эффекта. –

ответ

0

Поскольку вы сказали, что реализуется один задержка цикла, попробуйте больше задержки цикла, такие как:

process(CLK) is 
begin 
    if rising_edge(CLK) then 
    a_q <= a; 
    a_q_q <= a_q; 
    a_q_q_q <= a_q_q; 
    -- etc 
    end if; 
end process; 

Если вы хотите чистый код вы можете использовать цикл, чтобы задержать любого сигнала, как много циклов, как вы хотите, таких как

-- In Architecture 
constant num_cycles : INTEGER := 3; 
signal a_v : std_logic_vector(num_cycles downto 0); 

begin 
    a_v(0) <= a; 
    process(CLK) is 
    begin 
    if rising_edge(CLK) then 
     for i in 0 to num_cycles loop 
     a_v(i+1) <= a_v(i); 
     end loop; 
    end if; 
    end process; 
end architecture; 

В этом случае a может быть h_sync или v_sync. num_cycles - количество циклов, которые вы хотите отложить. a_v - вектор. Чтобы использовать задержанный сигнал, просто используйте a_v (num_cycles)

+0

Или вы можете сделать это за меньший код. Вместо 'a_v (0) <= a', устраните цикл for и сделайте' a_v <= a_v (num_cycles-1 до 0) & a; '. – PlayDough

+0

Yup сменный регистр также сделает трюк! :) – Renato

+0

Итак, из чего я понимаю, я помещаю 'a_v <= a_v (num_cycles-1 downto 0) & a' внутри предложения if, исключая цикл for? –

Смежные вопросы