1. FPGA视频图像处理开发环境搭建与第一个图像直通工程

任务目标

在 FPGA 开发板上搭建最小视频直通工程:摄像头(DVP 并口)→ 图像直通模块 → HDMI 输出。核心是验证三件事:像素时钟/同步信号(HSYNC、VSYNC、DE)时序正确、RGB565→RGB888 像素格式转换正确、整条链路能稳定显示实时画面。

环境与依赖

  • 开发板:Xilinx Artix-7(如 Basys3/Arty-A7)+ OV5640/OV7670 摄像头模块 + HDMI 输出(TMDS 或 RGB 转 HDMI 芯片)。
  • 工具:Vivado 2020.2 及以上,含 XDC 约束文件。
  • 时钟:摄像头 XCLK 由 FPGA 提供 24 MHz;像素时钟 PCLK 约 24~48 MHz;HDMI 像素时钟 74.25 MHz(720p60)。

数据链路

摄像头 DVP 并口 capture 同步/像素采样 RGB565→888 直通 HDMI/TMDS 720p60 输出 pclk / vsync / hsync / de pixel[23:0]

关键实现

摄像头输出 RGB565,HDMI 需要 RGB888。直通模块在 DE 有效时把每个像素的高 5/6/5 位左移补齐到 8 位,并同步传递 HSYNC/VSYNC/DE。下面给出核心 RTL 与顶层例化。

// rgb565_to_888.v —— 像素格式转换 + 同步信号直通
module rgb565_to_888 (
    input  wire        pclk,
    input  wire        rst_n,
    input  wire        de_in,
    input  wire        hsync_in,
    input  wire        vsync_in,
    input  wire [15:0] rgb565,
    output reg         de_out,
    output reg         hsync_out,
    output reg         vsync_out,
    output reg  [23:0] rgb888
);
    always @(posedge pclk or negedge rst_n) begin
        if (!rst_n) begin
            de_out <= 0; hsync_out <= 0; vsync_out <= 0; rgb888 <= 24'd0;
        end else begin
            de_out    <= de_in;
            hsync_out <= hsync_in;
            vsync_out <= vsync_in;
            // {R[4:0],R[4:2]} 补低位, {G[5:0],G[5:4]}, {B[4:0],B[4:2]}
            rgb888 <= {rgb565[15:11], rgb565[15:13],
                       rgb565[10:5],  rgb565[10:9],
                       rgb565[4:0],   rgb565[4:2]};
        end
    end
endmodule
// top.v —— 顶层:摄像头采集 → 直通 → HDMI
module top (
    input  wire       sys_clk,      // 100 MHz 板载
    input  wire       rst_btn,      // 复位按键
    // 摄像头 DVP
    input  wire       cam_pclk,
    input  wire       cam_vsync,
    input  wire       cam_hsync,
    input  wire       cam_de,
    input  wire [15:0] cam_data,
    output wire       cam_xclk,
    // HDMI
    output wire       hdmi_clk_p, hdmi_clk_n,
    output wire [2:0] hdmi_d_p,   hdmi_d_n
);
    wire rst_n = ~rst_btn;
    wire clk_24m, clk_pix, clk_5x, locked;

    // 摄像头 XCLK 24 MHz
    assign cam_xclk = clk_24m;

    // 时钟:24M 给摄像头,74.25M 像素时钟,5x 用于 TMDS 串行
    clk_wiz_0 u_clk (
        .clk_in1 (sys_clk),
        .clk_out1(clk_24m),
        .clk_out2(clk_pix),
        .clk_out3(clk_5x),
        .locked  (locked)
    );

    // 像素格式转换(直通核心)
    wire        de, hs, vs;
    wire [23:0] rgb888;
    rgb565_to_888 u_conv (
        .pclk     (cam_pclk),
        .rst_n    (rst_n & locked),
        .de_in    (cam_de),
        .hsync_in (cam_hsync),
        .vsync_in (cam_vsync),
        .rgb565   (cam_data),
        .de_out   (de),
        .hsync_out(hs),
        .vsync_out(vs),
        .rgb888   (rgb888)
    );

    // HDMI/TMDS 输出(Xilinx 原语封装)
    rgb2dvi_0 u_hdmi (
        .PixelClk  (clk_pix),
        .SerialClk (clk_5x),
        .aRst      (~rst_n),
        .vid_pData (rgb888),
        .vid_pHSync(hs),
        .vid_pVSync(vs),
        .vid_pVDE  (de),
        .TMDS_Clk_p(hdmi_clk_p),
        .TMDS_Clk_n(hdmi_clk_n),
        .TMDS_Data_p(hdmi_d_p),
        .TMDS_Data_n(hdmi_d_n)
    );
endmodule

约束与运行

在 XDC 中绑定摄像头 PCLK/VSYNC/HSYNC/DE/DATA 到对应引脚,HDMI 差分对绑定到 TMDS 引脚,sys_clk 绑定板载晶振。Vivado 中综合→实现→生成比特流→下载到板卡。

验证方法与通过条件

  1. 上电后 HDMI 显示器出现摄像头实时画面,无花屏、无撕裂。
  2. 用示波器/ILA 抓取 cam_pclk 与 cam_de:DE 有效期间每周期一个像素,HSYNC/VSYNC 极性符合摄像头数据手册。
  3. ILA 观察 rgb888 与 cam_data:当 cam_data=16'hF800(纯红)时 rgb888 应为 24'hFF0000,验证格式转换正确。
  4. 画面颜色与实物一致(红显红、绿显绿),说明 565→888 位拼接无误。

满足以上四点即判定直通链路时钟、同步与像素格式均正确。