一、DVP簡(jiǎn)介
DVP接口(Digital Video Port)是一種用于數(shù)字視頻傳輸?shù)牟⑿薪涌?,常見?a target="_blank">嵌入式系統(tǒng)和圖像傳感器中。DVP直接傳輸數(shù)字視頻信號(hào),減少模數(shù)轉(zhuǎn)換需求,適合中低速視頻傳輸。數(shù)據(jù)線:通常為8、10、12或16根數(shù)據(jù)線,用于傳輸像素?cái)?shù)據(jù)??刂菩盘?hào)包括像素時(shí)鐘(PCLK)、行同步(HSYNC 或 HREF)信號(hào)、場(chǎng)同步(VSYNC)等,用于同步數(shù)據(jù)傳輸。
DVP和VGA時(shí)序有相似之處,都使用行同步(HSYNC)和場(chǎng)同步(VSYNC)信號(hào)來同步圖像數(shù)據(jù)。區(qū)別在于DVP是數(shù)字接口,直接傳輸數(shù)字像素?cái)?shù)據(jù),包含像素時(shí)鐘(PCLK)和數(shù)據(jù)線;VGA是模擬接口,傳輸模擬RGB信號(hào),需數(shù)模轉(zhuǎn)換 。
本例介紹的DVP行同步信號(hào)采用 HREF,用于 ov5640 DVP數(shù)據(jù)接收采集。
(1)行時(shí)序
1.高電平有效:HREF為高電平時(shí),表示正在傳輸有效像素?cái)?shù)據(jù)。
2.像素傳輸:在HREF高電平期間,每個(gè)PCLK周期傳輸一個(gè)像素?cái)?shù)據(jù)。
3.行結(jié)束:HREF從高電平變?yōu)榈碗娖剑瑯?biāo)志一行數(shù)據(jù)傳輸完成。
4.像素?cái)?shù)據(jù)周期:ov5640 DVP每個(gè)有效數(shù)據(jù)為8位,數(shù)據(jù)采集時(shí)需要根據(jù)輸出格式進(jìn)行調(diào)整,輸出RGB565格式需要兩個(gè)像素時(shí)鐘才能完成傳輸,先傳輸高8位,后第8位。


(2)場(chǎng)時(shí)序
1.同步脈沖:VSYNC產(chǎn)生高電平脈沖(取決于極性,ov5640為高)表示新一幀開始。
2.有效數(shù)據(jù)期:新一幀開始一段時(shí)間后,每行數(shù)據(jù)通過HSYNC或HREF信號(hào)同步。
3.幀結(jié)束:一幀數(shù)據(jù)傳輸完成后,VSYNC再次產(chǎn)生脈沖,標(biāo)志下一幀的開始。

二、Verilog 實(shí)現(xiàn)
(1)設(shè)計(jì)要求
1. 對(duì) ov5640 輸出RGB565格式的圖像數(shù)據(jù)進(jìn)行接收
2. 接收數(shù)據(jù)輸出給存儲(chǔ)器(如rom、fifo、ddr)進(jìn)行存儲(chǔ),包含必要輸出端口
(2)設(shè)計(jì)要點(diǎn)
1. 場(chǎng)同步:每當(dāng) vsync 產(chǎn)生一次上升沿即代表新一幀的開始(上升沿通過打拍判斷)
2. 行同步:href 的每段高電平代表一行有效數(shù)據(jù)
3. 數(shù)據(jù)格式:一個(gè)pclk像素時(shí)鐘傳8位,而RGB565一個(gè)像素16位,需要兩個(gè)pclk像素時(shí)鐘才傳輸完一個(gè)像素?cái)?shù)據(jù),因此需要進(jìn)行先緩存高8位數(shù)據(jù),并在接收第8位時(shí)拼接數(shù)據(jù)并輸出
4. 數(shù)據(jù)有效信號(hào):高電平時(shí)代表當(dāng)前RGB565數(shù)據(jù)有效,可供后續(xù)存儲(chǔ)器作寫使能使用
(3)模塊代碼
`timescale 1ns / 1ps
module DVP_ctrl#(
parameter PIC_CNT_MAX = 4'd10 //舍棄前10幀不穩(wěn)定圖像數(shù)據(jù)
)(
input wire rst_n,
input wire ov5640_pclk, //攝像頭像素時(shí)鐘
input wire ov5640_href, //攝像頭行同步信號(hào)
input wire ov5640_vsync, //攝像頭場(chǎng)同步信號(hào)
input wire [7:0] ov5640_data, //攝像頭場(chǎng)數(shù)據(jù)輸入
output reg [15:0] RGB565_data, //圖像數(shù)據(jù)輸出(RGB565格式)
output wire data_valid //數(shù)據(jù)有效信號(hào)(給存儲(chǔ)器的寫使能信號(hào))
);
reg pix_flag; //一像素?cái)?shù)據(jù)結(jié)束標(biāo)志位
wire pic_flag; //一幀圖像結(jié)束標(biāo)志位
reg pic_valid; //幀有效標(biāo)志位
reg [3:0] pic_cnt; //幀計(jì)數(shù)器
reg [7:0] r_ov5640_data; //輸入數(shù)據(jù)緩存
reg ov5640_vsync_delay; //場(chǎng)同步信號(hào)打拍
reg pix_flag_delay; //一像素?cái)?shù)據(jù)結(jié)束標(biāo)志位打拍
//***************************** 場(chǎng)同步 ****************************//
//場(chǎng)同步信號(hào)打拍(用于檢測(cè)vsync上升沿)
always@(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
ov5640_vsync_delay <= 1'b0;
else
ov5640_vsync_delay <= ov5640_vsync;
//一幀圖像結(jié)束標(biāo)志位(vsync上升沿產(chǎn)生一次)
assign pic_flag = ((ov5640_vsync_delay == 1'b0) &&
(ov5640_vsync == 1'b1)) ? 1'b1 : 1'b0;
//前幾幀計(jì)數(shù),計(jì)滿產(chǎn)生幀有效信號(hào)
always @(posedge ov5640_pclk or negedge rst_n) begin
if (!rst_n) begin
pic_cnt <= 4'd0;
pic_valid <= 1'b0;
end else if (pic_flag) begin
if (pic_cnt == PIC_CNT_MAX) begin
pic_cnt <= 4'd0;
pic_valid <= 1'b1;
end else
pic_cnt <= pic_cnt + 4'd1;
end
end
//***************************** 行同步 ****************************//
//行同步
always @(posedge ov5640_pclk or negedge rst_n) begin
if (!rst_n) begin
pix_flag <= 1'b0;
r_ov5640_data <= 8'b0;
RGB565_data <= 8'b0;
end else if (ov5640_href) begin
if (!pix_flag) begin
r_ov5640_data <= ov5640_data; //先緩存高8位
pix_flag <= 1'b1;
end else begin
RGB565_data <= {r_ov5640_data , ov5640_data};//后拼接低8位輸出
pix_flag <= 1'b0;
end
end
end
//一像素?cái)?shù)據(jù)結(jié)束標(biāo)志位打拍(用于產(chǎn)生像素?cái)?shù)據(jù)有效信號(hào))
always@(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
pix_flag_delay <= 1'b0;
else
pix_flag_delay <= pix_flag;
//像素?cái)?shù)據(jù)有效信號(hào)
assign data_valid = pic_valid & pix_flag_delay;
endmodule
(4)仿真代碼
仿真就是給DVP模塊模擬ov5640產(chǎn)生的圖像數(shù)據(jù),我用的deepseek寫了一版,但經(jīng)過測(cè)試發(fā)現(xiàn)不能直接使用,于是根據(jù)它的框架自己進(jìn)行了一些修改,可以通過參數(shù)設(shè)置模擬圖像數(shù)據(jù)的參數(shù)(仿真多少幀、一幀多少行、一行多少像素)。以下模擬輸出了10幀、一幀8行數(shù)據(jù)、一行16個(gè)像素點(diǎn),同時(shí)DVP舍去前3幀圖像數(shù)據(jù)。
`timescale 1ns / 1ps
module DVP_data_gen_tb();
reg pclk; //像素時(shí)鐘 (10ns周期)
reg rst_n; //復(fù)位信號(hào) (低電平有效)
reg vsync; //場(chǎng)同步信號(hào)
reg href; //行同步信號(hào)
reg [7:0] data; //像素?cái)?shù)據(jù) (8bit)
wire data_valid; //數(shù)據(jù)有效信號(hào)
wire [15:0] RGB565_data; //輸出RGB565格式數(shù)據(jù) (16bit)
//模擬OV5640視頻數(shù)據(jù)生成
parameter WIDTH = 16, //寬(一行多少個(gè)像素)
HIGTH = 8, //高(一幀多少行數(shù)據(jù))
FRAME = 10; //幀(模擬發(fā)送多少幀數(shù)據(jù))
integer pixel_cnt = 0, //像素計(jì)數(shù)器
row_cnt = 0, //行計(jì)數(shù)器
frame_cnt = 0; //幀計(jì)數(shù)器
//時(shí)鐘(10ns周期)
always #5 pclk = ~pclk;
initial begin //初始化復(fù)位
pclk = 0;
rst_n = 0; #20;
rst_n = 1;
end
always @(posedge pclk or negedge rst_n) begin
if (!rst_n) begin
vsync <= 0;
href <= 0;
data <= 0;
pixel_cnt <= 0;
row_cnt <= 0;
frame_cnt <= 0;
end else begin
//******************************************模擬場(chǎng)同步信號(hào) (VSYNC)
if (pixel_cnt == 0 && row_cnt == 0) begin
vsync <= 1; // 一幀開始,VSYNC拉高一個(gè)時(shí)鐘周期
end else begin
vsync <= 0; // VSYNC拉低
end
//******************************************模擬行同步信號(hào) (HREF)
if (row_cnt < HIGTH*10 + 10) begin//一幀模擬HIGTH行,多余行模擬行與行之間的輸出間隔
if (row_cnt <10 || (row_cnt % 10)!=0)
row_cnt <= row_cnt + 1;
else begin
if (pixel_cnt < WIDTH) begin
href <= 1; //HREF高電平表示行數(shù)據(jù)傳輸
data <= data + 1; //像素?cái)?shù)據(jù)每次自增1
pixel_cnt <= pixel_cnt + 1;
end else begin
//一行結(jié)束
href <= 0; //HREF低電平表示行結(jié)束
pixel_cnt <= 0;
row_cnt <= row_cnt + 1; //行計(jì)數(shù)器加1
end
end
end else begin//一幀結(jié)束
href <= 0;
data <= 0;
row_cnt <= 0; //重置行計(jì)數(shù)器
frame_cnt <= frame_cnt + 1; //幀計(jì)數(shù)器加1
end
//******************************************模擬FRAME幀后結(jié)束測(cè)試
if (frame_cnt == FRAME) begin
$finish; // 結(jié)束仿真
end
end
end
DVP_ctrl #(
.PIC_CNT_MAX (4'd3) //舍去前三幀圖像
) DVP_ctrl (
.ov5640_pclk (pclk),
.rst_n (rst_n),
.ov5640_vsync (vsync),
.ov5640_href (href),
.ov5640_data (data),
.data_valid (data_valid),
.RGB565_data (RGB565_data)
);
endmodule
三、仿真波形
完整波形:可以看到一共發(fā)送了10幀數(shù)據(jù),同時(shí)data_valid在前三幀保持為0,后面才開始變化,說明前三幀數(shù)據(jù)被成功舍去。

一幀波形:1幀包含8行,1行有16個(gè)8位數(shù)據(jù)。

一行波形:一個(gè)RGB565像素?cái)?shù)據(jù)對(duì)應(yīng)兩個(gè)8位數(shù)據(jù),可以看到每接收2個(gè)數(shù)據(jù)就相應(yīng)拼接輸出1個(gè)RGB565數(shù)據(jù),同時(shí)data_valid數(shù)據(jù)有效信號(hào)與數(shù)據(jù)同步產(chǎn)生。

-
FPGA
+關(guān)注
關(guān)注
1659文章
22364瀏覽量
632986 -
接口
+關(guān)注
關(guān)注
33文章
9490瀏覽量
156577 -
圖像傳感器
+關(guān)注
關(guān)注
68文章
2065瀏覽量
132022 -
Verilog
+關(guān)注
關(guān)注
30文章
1373瀏覽量
114325 -
VGA
+關(guān)注
關(guān)注
5文章
577瀏覽量
66069
原文標(biāo)題:基于FPGA的DVP接口實(shí)現(xiàn)
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
【FPGA設(shè)計(jì)實(shí)例】FPGA接口實(shí)現(xiàn)文本液晶顯示模塊
基于JTAG接口實(shí)現(xiàn)ARM的FPGA在線配置設(shè)計(jì)
學(xué)fpga的內(nèi)部結(jié)構(gòu)和各接口實(shí)驗(yàn)怎么學(xué)
基于FPGA的腦機(jī)接口實(shí)時(shí)系統(tǒng)設(shè)計(jì)
如果不使用FPGA自帶的SERDES,可否適用LVDS接口實(shí)現(xiàn)其功能?
通過USB接口實(shí)現(xiàn)FPGA 的SelectMap配置
基于JTAG接口實(shí)現(xiàn)ARM的FPGA在線配置設(shè)計(jì)
ARM與FPGA的接口實(shí)現(xiàn)的解析
基于FPGA的SDRAM串口實(shí)驗(yàn)
C#-Interface接口實(shí)現(xiàn)
基于XML語言描述的接口實(shí)現(xiàn)方法
基于FPGA的DVP接口實(shí)現(xiàn)
評(píng)論