VHDL - 从VGA的帧缓冲区读取

时间:2016-03-03 10:16:42

标签: graphics vhdl fpga vga picoblaze

我有一个FPGA学校项目,我遇到了一些问题。我们正在使用Digilent的Nexys2板(Xilinx XC3S500E FPGA)。

我们制作了一些控制器,包括带有帧缓冲器的VGA(640x480)。至少我们称它为帧缓冲 - 它实际上是一个分布式30x40 RAM,用于存储要显示的像素(1位 - “一个方块”,所以我们实际上有30 x 40分辨率,没有颜色)。

然后我们使用8位Picoblaze微控制器核心,现在我们必须建立一个Snake游戏(你知道,来自旧的Nokias)。现在我的问题是Picoblaze只有一个64字节的暂存器RAM,所以如果我将它保留在那里,那么蛇就不会变得很长。

所以我想我可以从VGA的RAM中读取蛇的位置,但我不知道如何,因为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
);

如何在PC中解决这个问题?从显卡的内存中读取是否常见? 我有什么选择?我可以使用两个时钟的Block RAM,一个用于VGA读取,另一个用于picoblaze,但我不知道,也无法找到如何正确生成另一个时钟信号。

1 个答案:

答案 0 :(得分: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而不是反激信号上触发该过程。