rk3588's 小破站 - vivado
type: channel
link: http://8.162.1.103/index.php/tag/vivado/
items: FPGA开发（三）OV5640 摄像头接入与 DVP 视频捕获
items: FPGA开发（二）软硬协同的帧缓存架构
items: FPGA开发（一）基础视频输出与彩条测试

FPGA开发（三）OV5640 摄像头接入与 DVP 视频捕获
type: item
date: 2026-07-07T19:45:00+08:00
description: 阶段目标：I2C 配置摄像头寄存器，DVP视频流接收，将捕获的视频帧写入 DDR2，通过 VDMA 显示实时摄像头画面输出结果：VGA 显示器实时显示 OV5640 摄像头采集的画面设备：NEXYS A7开发板架构梳理：使用 I2C (SCCB 协议) 访问 0x3C 器件地址，读取 0x300A/B 寄存器获取 0x5640 ID。自定义 DVP to AXI-Stream IP：编写精简 Verilog，利用 PCLK 将 8 位数据 (D[7:0]) 拼接为 16 位 RGB565，并转换 VSYNC/HREF 为 tuser/tvalid/tlast 握手信号。VDMA S2MM 闭环：重新开启 VDMA 写通道，将摄像头数据源源不断地写入 DDR 显存的首地址。系统总体架构硬件模块配置1. OV5640 摄像头接口作用：提供视频流信号手写模块暴露接口`timescale 1ns / 1ps module ov5640_dvp_to_axis #( parameter integer H_ACTIVE = 640, parameter integer V_ACTIVE = 480, parameter integer FIFO_ADDR_WIDTH = 12, parameter VSYNC_ACTIVE_HIGH = 1'b1, parameter HREF_ACTIVE_HIGH = 1'b1, parameter RGB565_BYTE_ORDER = 1'b0, parameter SWAP_RB = 1'b0 ) ( input wire pclk, input wire rstn, input wire cam_vsync, input wire cam_href, input wire [7:0] cam_data, output wire m_axis_video_tvalid, input wire m_axis_video_tready, output wire [23:0] m_axis_video_tdata, output wire [0:0] m_axis_video_tuser, output wire [0:0] m_axis_video_tlast, output wire probe_pixel_valid, output wire [15:0] probe_rgb565, output wire [15:0] probe_x, output wire [15:0] probe_y, output reg probe_overflow ); reg vsync_d; reg href_d; reg [7:0] data_d; reg byte_phase; reg [7:0] first_byte; reg [15:0] rgb565; reg [15:0] x_cnt; reg [15:0] y_cnt; reg line_has_pixel; reg sof_pending; reg frame_active; localparam integer FIFO_DEPTH = (1 << FIFO_ADDR_WIDTH); localparam integer FIFO_COUNT_WIDTH = FIFO_ADDR_WIDTH + 1; localparam [FIFO_COUNT_WIDTH-1:0] FIFO_DEPTH_COUNT = (1 << FIFO_ADDR_WIDTH); reg [25:0] fifo_mem [0:FIFO_DEPTH-1]; reg [FIFO_ADDR_WIDTH-1:0] fifo_wr_ptr; reg [FIFO_ADDR_WIDTH-1:0] fifo_rd_ptr; reg [FIFO_COUNT_WIDTH-1:0] fifo_count; reg pixel_push; reg [23:0] pixel_data; reg pixel_user; reg pixel_last; wire fifo_empty = (fifo_count == {FIFO_COUNT_WIDTH{1'b0}}); wire fifo_full = (fifo_count == FIFO_DEPTH_COUNT); wire fifo_pop = m_axis_video_tready && !fifo_empty; wire fifo_push = pixel_push && !fifo_full; wire vsync_active = VSYNC_ACTIVE_HIGH ? cam_vsync : ~cam_vsync; wire href…

FPGA开发（二）软硬协同的帧缓存架构
type: item
date: 2026-07-07T19:38:00+08:00
description: 阶段目标：在第一步的基础上，集成 VDMA 和 DDR2 内存，实现从帧缓存读取并显示图像。输出结果：Cortex-M3 软核在 DDR2 中写入图像数据，VDMA 自动读取并通过 VGA 显示设备：NEXYS A7开发板架构梳理：MIG 7 Series：配置 DDR 物理层控制器，提供 ui_clk 和高带宽 AXI-MM 接口。AXI VDMA (MM2S 通道)：配置为单缓冲循环读取模式，作为纯粹的像素中转。Cortex-M3 软核控制：通过 AXI-Lite 接口向 VDMA 下发寄存器配置（源地址、HSIZE、VSIZE），启动传输。和第一步不同在于，第一步图像是实时生成实时显示，这一步会多一个帧缓存的步骤，M3写入DDR一幅图片由VDMA进行读取系统总体架构硬件模块配置1. AXI VDMA作用：自动从 DDR2 读取帧缓存，转换为 AXI Stream 视频流传统方式：CPU 循环读取每个像素 → 写到 Video Out 问题: CPU 占用高VDMA 方式：配置一次 → VDMA 自动循环读取 优势: CPU 只需写帧缓存，显示自动刷新可以先取消勾选Enable Write Channel，只启用Enable Read Channel，Stream Data Width根据自己需要更改2. MIG (Memory Interface Generator) - DDR2 控制器作用：提供 DDR2 SDRAM 的 AXI4 接口配置比较麻烦，建议参考自己板子的手册，找官方的DDR约束。3. AXI SmartConnect作用：用于管理多个 AXI 主设备（Master）和从设备（Slave）之间互联和仲裁配置好主从通道数即可时钟方案Clocking Wizard 配置根据mig里的实际配置新增时钟供给clk_ref_i和sys_clk_imig输出的ui_clk时钟域：AXI SmartConnect m_axi_mm2s_aclk接线首先求助Run Connection Automation大人记得从AXI Interconnect引出来M0x_AXI给VDMA，保证M3软核对DDR的访问数据平面：读取 VDMA->AXI SmartConnect->Memory Interface Generator (MIG 7 Series)​ 输出 VDMA->AX14-Stream to Video Out->rgb888_to_rgb444_vga_v1_0控制平面：Cortex-M3->AXI Interconnect尾声Generate Output ProductsCreate HDL Wrapper分配引脚生成.xdc综合实现生成比特流

FPGA开发（一）基础视频输出与彩条测试
type: item
date: 2026-07-07T19:34:00+08:00
description: 阶段目标：建立可靠的视频时序基准，排除物理显示器和 VGA 接口的干扰，验证视频时序和信号完整性输出结果：VGA 显示器显示标准彩色测试条纹设备：NEXYS A7开发板架构梳理：手写axis_colorbar替代真实视频源，生成标准 AXI-Stream 像素流。Video Timing Controller (VTC) 提供精确的 HSYNC、VSYNC 和 VDE 时序信号。AXI4-Stream to Video Out 模块完成握手，将流数据与时序强绑定。系统总体架构硬件模块配置1. Video Timing Controller (VTC)作用：生成 VGA 640×480 @ 60Hz 标准时序信号取消勾选Include AXI4-Lite Interface，暂不需要总线参与；取消勾选Enable Detection然后记得Video Mode 调到自己预期的分辨率，如果为了适配OV5640这里设置成480p。其他保持默认就行2. AXI4-Stream to Video Out作用：将 AXI Stream 视频数据转换为标准并行 VGA 接口Clock Mode调成independent方便像素时钟接入。可选适当调大FIFO Depth，避免缓冲深度不足而卡顿。其他可保持默认3. ColorBar 彩条生成器作用：实时生成标准测试条纹为什么不用TPG IP?，，用这个可能在综合时报错module 'design_1_v_tpg_0_0_v_tpg' not found，可能和底层不是verilog而是C实现有关，比较麻烦。既然只是做个测试图像，直接手写一个或许更简单一点。`timescale 1ns / 1ps module axis_colorbar #( parameter integer H_ACTIVE = 640, parameter integer V_ACTIVE = 480 ) ( input wire ap_clk, input wire ap_rst_n, output wire m_axis_video_tvalid, input wire m_axis_video_tready, output wire [23:0] m_axis_video_tdata, output wire [0:0] m_axis_video_tuser, output wire [0:0] m_axis_video_tlast ) localparam integer X_BITS = 16; localparam integer Y_BITS = 16; reg [X_BITS-1:0] x_cnt; reg [Y_BITS-1:0] y_cnt; wire axis_fire = m_axis_video_tvalid && m_axis_video_tready; wire line_last = (x_cnt == H_ACTIVE - 1); wire frame_last = line_last && (y_cnt == V_ACTIVE - 1); always @(posedge ap_clk) begin if (!ap_rst_n) begin x_cnt <= {X_BITS{1'b0}}; y_cnt <= {Y_BITS{1'b0}}; end else if (axis_fire) begin if (line_last) begin x_cnt <= {X_BITS{1'b0}}; if (frame_last) begin y_cnt <= {Y_BITS{1'b0}}; end else begin y_cnt <= y_cnt + 1'b1; end end else begin x_cnt <= x_cnt + 1'b1; end end end function [23:0] color_bar; input [X_BITS-1:0] xpos; begin if (xpos < (H_ACTIVE * 1 / 8)) begin color_bar = 24'hffffff; end else if (xpos < (H_ACTIVE * 2 / 8)) begin color_bar = 24'hffff00; end else if (xpos < (H_ACTIVE * 3 / 8)) begin color_bar = 24'h00ffff; end else if (xpos < (H_ACTIVE * 4 / 8)) begin color_bar = 24'h00ff00; end else if (xpos < (H_ACTIVE * 5 / 8)) …