You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vivado中ZedBoard双块存储器的访问与图像写入方法咨询

ZedBoard FPGA双端口RAM访问与图像写入问题解答

问题描述

希望通过VGA接口将ZedBoard FPGA中的图像显示到屏幕上,已创建双块存储器(双端口RAM)用于存储图像并读取显示,但不清楚如何访问该存储器及写入图像。以下是top_module的例化代码:

entity top_module is
    Port ( 
        clk100        : in    STD_LOGIC;
        vga_red      : out   STD_LOGIC_VECTOR(3 downto 0);
        vga_green    : out   STD_LOGIC_VECTOR(3 downto 0);
        vga_blue     : out   STD_LOGIC_VECTOR(3 downto 0);
        vga_hsync    : out   STD_LOGIC;
        vga_vsync    : out   STD_LOGIC
        
    
     );
end top_module;

architecture Behavioral of top_module is

    

component clocking
port
 (-- Clock in ports
  CLK_100           : in     std_logic;
  -- Clock out ports
  CLK_50          : out    std_logic;
  CLK_25          : out    std_logic
 );
end component;

    
    COMPONENT blk_mem_gen_0
    PORT (
        clka  : IN  STD_LOGIC;
        wea   : IN  STD_LOGIC_VECTOR(0 DOWNTO 0);
        addra : IN  STD_LOGIC_VECTOR(18 DOWNTO 0);
        dina  : IN  STD_LOGIC_VECTOR(11 DOWNTO 0);
        clkb  : IN  STD_LOGIC;
        addrb : IN  STD_LOGIC_VECTOR(18 DOWNTO 0);
        doutb : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
    );
    END COMPONENT;

    COMPONENT capture
    PORT(
        pclk : IN std_logic ;        
        addr  : OUT std_logic_vector(18 downto 0);
        dout  : OUT std_logic_vector(11 downto 0);
        we    : OUT std_logic
        );
    END COMPONENT;

    COMPONENT vga
    PORT(
        clk25     : IN std_logic;
        vga_red   : OUT std_logic_vector(3 downto 0);
        vga_green : OUT std_logic_vector(3 downto 0);
        vga_blue  : OUT std_logic_vector(3 downto 0);
        vga_hsync : OUT std_logic;
        vga_vsync : OUT std_logic;
        
        frame_addr  : OUT std_logic_vector(18 downto 0);
        frame_pixel : IN  std_logic_vector(11 downto 0)         
        );
    END COMPONENT;
    
    signal frame_addr      : std_logic_vector(18 downto 0);
    signal frame_pixel     : std_logic_vector(11 downto 0);

    signal capture_addr    : std_logic_vector(18 downto 0);
    signal capture_data    : std_logic_vector(11 downto 0);
   signal capture_we      : std_logic_vector(0 downto 0);
    signal resend          : std_logic;
    signal config_finished : std_logic;
    
    signal clk_feedback  : std_logic;
    signal clk50u        : std_logic;
    signal clk50         : std_logic;
    signal clk25u        : std_logic;
    signal clk25         : std_logic;
    signal buffered_pclk : std_logic;
    
begin
  

    Inst_vga: vga PORT MAP(
        clk25       => clk25,
        vga_red     => vga_red,
        vga_green   => vga_green,
        vga_blue    => vga_blue,
        vga_hsync   => vga_hsync,
        vga_vsync   => vga_vsync,
        frame_addr  => frame_addr,
        frame_pixel => frame_pixel
    );

fb : blk_mem_gen_0
  PORT MAP (
    clka  => CLK50 ,
    wea   => capture_we,
    addra => capture_addr,
    dina  => capture_data,
     
    clkb  => CLK50,
    addrb => frame_addr,
    doutb => frame_pixel
  );
  
capture: ov7670_capture PORT MAP(
        pclk  => CLK50 , 
        addr  => capture_addr,
        dout  => capture_data,
        we    => capture_we(0)
    );
  


your_instance_name : clocking
  port map
   (-- Clock in ports
    CLK_100 => CLK100,
    -- Clock out ports
    CLK_50 => CLK50,
    CLK_25 => CLK25);

end Behavioral ;

双端口RAM访问与图像写入说明

1. 现有双端口RAM的工作逻辑

你使用的blk_mem_gen_0是Xilinx双端口RAM IP,两个端口独立工作:

  • 写端口(Port A):由CLK50驱动,addra指定写入地址,dina传入11位像素数据(对应RGB444格式:4位红、4位绿、3位蓝),wea为写使能信号(高电平有效)。
  • 读端口(Port B):同样由CLK50驱动,addrb指定读取地址,doutb输出对应地址的像素数据,直接传给VGA模块用于显示。

当前代码中,ov7670_capture模块已承担图像写入功能:它输出的capture_addr、capture_data、capture_we分别连接到RAM的写端口,实现从OV7670摄像头采集图像并写入RAM。

2. 自定义图像写入的实现方式

若无需摄像头采集,要写入自定义图像,可采用以下方案:

方案一:RAM初始化加载静态图像

配置blk_mem_gen_0时,选择“Load Init File”,导入提前生成的COE文件。COE文件按地址顺序存储图像的RGB444像素数据,FPGA上电后RAM会自动加载这些数据,VGA模块直接读取显示。

方案二:逻辑生成写信号写入图像

替换ov7670_capture模块,编写自定义写入逻辑:

  • 用计数器生成addra地址,从0递增到RAM最大地址;
  • 预存图像像素数据(通过常量数组定义),作为dina输入;
  • 复位完成后,拉高wea信号,将所有像素数据依次写入RAM。

简化示例逻辑:

signal write_cnt : std_logic_vector(18 downto 0) := (others => '0');
signal img_data : std_logic_vector(11 downto 0);
-- 定义图像数据数组,需填充完整像素数据
type img_array is array(0 to 524287) of std_logic_vector(11 downto 0);
constant my_image : img_array := (x"000", x"111", ...); 

process(clk50)
begin
    if rising_edge(clk50) then
        if reset = '1' then
            write_cnt <= (others => '0');
            capture_we <= "0";
        else
            if write_cnt < x"7FFFF" then -- 19位地址最大值
                capture_addr <= write_cnt;
                img_data <= my_image(to_integer(unsigned(write_cnt)));
                capture_we <= "1";
                write_cnt <= write_cnt + 1;
            else
                capture_we <= "0";
            end if;
        end if;
    end if;
end process;

方案三:通过PS端AXI总线写入图像

利用ZedBoard的PS(ARM)部分,通过AXI接口将图像数据从PS传到PL端RAM。需添加AXI Slave IP(如AXI BRAM Controller)并与双端口RAM连接,再在PS端编写程序,通过AXI总线发送图像数据。

3. 现有代码检查要点

  • 确认clocking模块是否正确生成50MHz和25MHz时钟,VGA模块需25MHz时钟驱动(对应640x480@60Hz分辨率);
  • 确认vga模块输出的frame_addr范围与RAM地址空间匹配(19位地址对应524288个存储单元,适配QVGA(320x240)或VGA(640x480)分辨率);
  • 若使用摄像头,需确保ov7670_capture模块的pclk信号与摄像头输出的像素时钟匹配(当前代码连接的是CLK50,需确认摄像头参数)。

内容的提问来源于stack exchange,提问作者Thabet thabet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:40:11