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
相关产品推荐
相关产品推荐

