1. 图像传感器接口时序仿真

图像传感器接口时序仿真 学习卡片

任务目标

设计一个CMOS图像传感器接口的时序仿真模型,实现像素时钟(PCLK)、行同步(HSYNC)、帧同步(VSYNC)与像素数据(DATA)的同步采集与解析,验证输出像素坐标与数据值的正确性。

环境依赖

Verilog仿真环境(Icarus Verilog / ModelSim / VCS均可),无需额外IP核。

接口时序定义

采用类OV5640的DVP并行接口时序:

  • PCLK:像素时钟,数据在上升沿有效
  • VSYNC:帧同步,高电平表示有效帧(本设计为高有效)
  • HSYNC:行同步,高电平表示有效像素输出
  • DATA[7:0]:8位像素数据,仅在VSYNC与HSYNC同时为高时有效

仿真参数:分辨率8×5(宽8像素,高5行),PCLK周期10ns。

关键完整代码

// sensor_interface_tb.v
`timescale 1ns/1ps

module sensor_interface_tb;

// 参数定义
localparam H_ACTIVE = 8;   // 行有效像素数
localparam V_ACTIVE = 5;   // 帧有效行数
localparam H_TOTAL  = 12;  // 行总周期(含消隐)
localparam V_TOTAL  = 8;   // 帧总行数(含消隐)

// 信号声明
reg         pclk = 0;
reg         vsync = 0;
reg         hsync = 0;
reg  [7:0]  data = 8'h00;
wire [3:0]  pixel_x;
wire [2:0]  pixel_y;
wire        data_valid;
wire [7:0]  pixel_data;

// 生成PCLK:10ns周期
always #5 pclk = ~pclk;

// 被测模块:像素采集与同步解析
pixel_capture u_capture (
    .pclk      (pclk),
    .vsync     (vsync),
    .hsync     (hsync),
    .data_in   (data),
    .pixel_x   (pixel_x),
    .pixel_y   (pixel_y),
    .data_valid(data_valid),
    .pixel_data(pixel_data)
);

// 图像传感器时序生成
integer h_cnt, v_cnt;
initial begin
    // 初始化
    h_cnt = 0;
    v_cnt = 0;
    vsync = 0;
    hsync = 0;
    data  = 8'h00;

    // 等待PCLK稳定
    #20;

    // 产生一帧数据
    repeat (V_TOTAL) begin
        // 行循环
        for (h_cnt = 0; h_cnt < H_TOTAL; h_cnt = h_cnt + 1) begin
            @(posedge pclk);
            // 帧同步:前2行为消隐,后V_ACTIVE行为有效
            if (v_cnt >= 2 && v_cnt < 2 + V_ACTIVE) begin
                vsync = 1;
                // 行同步:前2个PCLK为行消隐,后H_ACTIVE个为有效像素
                if (h_cnt >= 2 && h_cnt < 2 + H_ACTIVE) begin
                    hsync = 1;
                    data = (v_cnt - 2) * H_ACTIVE + (h_cnt - 2); // 像素值 = 行*宽+列
                end else begin
                    hsync = 0;
                    data = 8'h00;
                end
            end else begin
                vsync = 0;
                hsync = 0;
                data = 8'h00;
            end
        end
        v_cnt = v_cnt + 1;
    end

    // 帧结束
    vsync = 0;
    hsync = 0;
    data = 8'h00;
    #50;
    $finish;
end

// 数据采集监控
always @(posedge pclk) begin
    if (data_valid) begin
        $display("时间=%0t, 坐标=(%0d,%0d), 像素值=0x%02h, 期望值=0x%02h %s",
                 $time, pixel_x, pixel_y, pixel_data,
                 (pixel_y * H_ACTIVE + pixel_x),
                 (pixel_data == (pixel_y * H_ACTIVE + pixel_x)) ? "PASS" : "FAIL");
    end
end

// 仿真结束条件:完成一帧后停止
initial begin
    #2000;
    $display("仿真超时,强制结束");
    $finish;
end

endmodule

// 像素采集模块
module pixel_capture (
    input  wire       pclk,
    input  wire       vsync,
    input  wire       hsync,
    input  wire [7:0] data_in,
    output reg  [3:0] pixel_x,
    output reg  [2:0] pixel_y,
    output reg        data_valid,
    output reg  [7:0] pixel_data
);

// 内部计数器
reg [3:0] x_cnt;
reg [2:0] y_cnt;

always @(posedge pclk) begin
    if (!vsync) begin
        // 帧消隐:复位
        x_cnt <= 0;
        y_cnt <= 0;
        data_valid <= 0;
    end else if (!hsync) begin
        // 行消隐:列清零,行不变
        x_cnt <= 0;
        data_valid <= 0;
    end else begin
        // 有效像素
        pixel_x   <= x_cnt;
        pixel_y   <= y_cnt;
        pixel_data <= data_in;
        data_valid <= 1;
        if (x_cnt == H_ACTIVE - 1) begin
            x_cnt <= 0;
            y_cnt <= y_cnt + 1;
        end else begin
            x_cnt <= x_cnt + 1;
        end
    end
end

endmodule

运行方式

iverilog -o sensor_tb sensor_interface_tb.v
vvp sensor_tb

验证方法与通过条件

仿真运行后,终端将逐行打印每个有效像素的坐标、采集值与期望值。通过条件:

  • 共打印40行(8×5个像素),每行均以PASS结尾
  • 坐标范围:pixel_x为0~7,pixel_y为0~4
  • 像素值满足:pixel_data == pixel_y * 8 + pixel_x
  • 无FAIL出现,仿真正常结束(非超时强制结束)

预期输出示例

时间=70, 坐标=(0,0), 像素值=0x00, 期望值=0x00 PASS
时间=90, 坐标=(1,0), 像素值=0x01, 期望值=0x01 PASS
...
时间=470, 坐标=(7,4), 像素值=0x27, 期望值=0x27 PASS

若所有像素均PASS,则证明接口时序解析正确,像素坐标与数据同步采集功能实现完整。