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,则证明接口时序解析正确,像素坐标与数据同步采集功能实现完整。