VHDL - 从 VGA 的帧缓冲区读取

VHDL - reading from VGA's framebuffer

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

我们构建了一些控制器,包括带有帧缓冲区的 VGA (640x480)。至少我们称它为帧缓冲区 - 它实际上是一个分布式 30x40 RAM,用于存储要显示的像素(1 位 - "one square",所以我们实际上有一个 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 中是如何解决的?从显卡的内存中读取是否很常见? 我在这里有什么选择?我可以使用带有两个时钟的块 RAM,一个用于 VGA 读取,另一个用于 picoblaze,但我不知道也无法找到如何正确生成另一个时钟信号。

我会像这样定义一个仅在反激期间有效的第二个读取端口:

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 而不是反激信号上触发该过程。