2016-03-03 3 views
-1

У меня есть школьный проект FPGA, и у меня проблемы. Мы используем плату Nexys2 от Digilent (Xilinx XC3S500E FPGA).VHDL - чтение из фреймбуфера VGA

Мы построили несколько контроллеров, включая VGA (640x480) с фреймбуром. По крайней мере, мы назвали его фреймбууром - на самом деле это распределенная оперативная память 30x40, в которой хранятся пиксели (1 бит - «один квадрат», поэтому у нас есть разрешение 30 на 40, без цветов).

Затем мы использовали 8-разрядное ядро ​​микроконтроллера Picoblaze, и теперь нам нужно построить игру Snake (вы знаете, тот, что из старого Nokias). Теперь моя проблема в том, что у Picoblaze есть только 64-байтовая RAM-память, поэтому змея не может стать очень длинной, если я сохраню ее там.

Так что я думал, что могу просто прочитать, где змея из ОЗУ VGA, но я не знаю, как, как VGA читает от нее, и есть проблема адресации или чтения всей строки данных (picoblaze имеет 8-бит in_port). Вот процесс:

process(clk_i, vert_data_on, hor_data_on, read_data) 
begin 
    if vert_data_on = '1' and hor_data_on = '1' then 
     if read_data(conv_integer(column_calc)) = '1' then 
      red_o <= "000"; 
      green_o <= "000"; 
      blue_o <= "00"; 
     else 
      red_o <= "111"; 
      green_o <= "111"; 
      blue_o <= "11"; 
     end if; 
    else    
     red_o <= "000"; 
     green_o <= "000"; 
     blue_o <= "00"; 
    end if; 
end process; 

Компонент RAM и его экземпляр:

component RAM30x40 is 
    Port(
     clk_i   : in STD_LOGIC; 
     we_i   : in STD_LOGIC; 
     addrInX_i  : in STD_LOGIC_VECTOR(5 downto 0); 
     addrInY_i  : in STD_LOGIC_VECTOR(4 downto 0); 
     addrOutY_i  : in STD_LOGIC_VECTOR(4 downto 0); 
     data_i   : in STD_LOGIC; 
     data_o   : out STD_LOGIC_VECTOR(0 to 39) 
    ); 
end component; 

inst_RAM: RAM30x40 
Port map(
    clk_i   => clk_i, 
    we_i   => write_enable, 
    addrInX_i  => write_addr_x, 
    addrInY_i  => write_addr_y, 
    addrOutX_i  => read_addr_x, 
    addrOutY_i  => row_calc, 
    data_i   => write_data, 
    data_o   => read_data 
); 

Как это решается в ПК? Обычно ли это читать из памяти графической карты? Какие у меня варианты? Я мог бы использовать блок RAM с двумя часами и иметь один для чтения VGA, а другой для picoblaze, но я не знаю и не могу найти, как правильно генерировать другой тактовый сигнал.

+1

Я думаю, что это не так, чтобы читать из буфера чтения VGA. Ваша игровая логика должна иметь свое собственное текущее состояние поля и змеи. Выложенный процесс имеет в своем списке чувствительности 'clk_i', но не описывает синхронную логику. Это предназначено? И 'column_calc' отсутствует, если это должен быть комбинационный процесс. –

+0

Если память блокнота недостаточно велика, вы должны рассмотреть возможность добавления внешнего BRAM в ваш проект Picoblaze для хранения данных. вам может потребоваться некоторая логика клея, такая как выходной порт для адреса BRAM и т. д., есть много документации о том, как работает I/O для процессора Picoblaze. – damage

+0

'vert_data_on' и' horiz_data_on', по-видимому, используются для горизонтального и вертикального обратного хода. Выход VGA не нуждается в памяти в течение этого таймфрейма. Вы не показываете, как вы генерируете эти сигналы, но, вероятно, достаточно времени, чтобы сделать что-то еще с памятью во время этого. – mfro

ответ

0

Я бы просто определить второй чтения порт, который активен только во время обратного хода, как это:

process(clk_i, vert_data_on, hor_data_on, read_data) 
begin 
    if vert_data_on = '1' and hor_data_on = '1' then 
     if read_data(conv_integer(column_calc)) = '1' then 
      red_o <= "000"; 
      green_o <= "000"; 
      blue_o <= "00"; 
     else 
      red_o <= "111"; 
      green_o <= "111"; 
      blue_o <= "11"; 
     end if; 
     data2_valid <= '0'; 
    else    
     red_o <= "000"; 
     green_o <= "000"; 
     blue_o <= "00"; 

     read_data2 <= conv_integer(read_request2); 
     data2_valid <= '1'; 
    end if; 
end process; 

data2_valid затем определить триггер для действительных данных от read_request2 адреса. Однако, скорее всего, вы должны запустить процесс на clk_i вместо сигналов обратного хода.

+0

Как я уже сказал, я решил пойти на более крупный двойной порт BRAM с теми же часами для обоих портов, поэтому я сделал это немного по-другому. Но это полезно, поэтому я буду принимать его в качестве ответа (но я не могу выдвинуть его из-за моей низкой репутации). – Luka