2016-03-03 50 views
-1

我有一個FPGA學校項目,我有一些問題。我們使用Digilent的Nexys2板(Xilinx XC3S500E FPGA)。VHDL - 從VGA的幀緩衝讀取

我們用一個幀緩衝器構建了一些包括VGA(640x480)的控制器。至少我們稱它爲幀緩衝 - 實際上它是一個分佈式的30x40 RAM,用於存儲要顯示的像素(1位 - 「一個方塊」,所以我們實際上具有30乘40分辨率,無顏色)。然後,我們使用了8位Picoblaze微控制器內核,現在我們必須構建一個Snake遊戲(你知道,來自舊Nokias的遊戲)。現在我的問題是,Picoblaze只有64字節的暫存器內存,所以如果我把它放在那裏,蛇不會變得很長。

所以我一直在想我可以從VGA的RAM中讀出蛇的位置,但我不知道如何,因爲VGA正在讀取它,並且還存在尋址或讀取整行數據的問題(picoblaze has一個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 
); 

這是如何解決在電腦?從圖形卡的內存中讀取是否很常見? 這裏有什麼我的選擇?我可以使用兩個時鐘的Block 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