一、DVP簡介
DVP接口(Digital Video Port)是一種用于數(shù)字視頻傳輸?shù)牟⑿薪涌冢R娪?a target="_blank">嵌入式系統(tǒng)和圖像傳感器中。DVP直接傳輸數(shù)字視頻信號,減少模數(shù)轉(zhuǎn)換需求,適合中低速視頻傳輸。數(shù)據(jù)線:通常為8、10、12或16根數(shù)據(jù)線,用于傳輸像素數(shù)據(jù)??刂菩盘柊ㄏ袼?a href="http://www.www27dydycom.cn/tags/時鐘/" target="_blank">時鐘(PCLK)、行同步(HSYNC 或 HREF)信號、場同步(VSYNC)等,用于同步數(shù)據(jù)傳輸。
DVP和VGA時序有相似之處,都使用行同步(HSYNC)和場同步(VSYNC)信號來同步圖像數(shù)據(jù)。區(qū)別在于DVP是數(shù)字接口,直接傳輸數(shù)字像素數(shù)據(jù),包含像素時鐘(PCLK)和數(shù)據(jù)線;VGA是模擬接口,傳輸模擬RGB信號,需數(shù)模轉(zhuǎn)換 。
本例介紹的DVP行同步信號采用 HREF,用于 ov5640 DVP數(shù)據(jù)接收采集。
(1)行時序
1.高電平有效:HREF為高電平時,表示正在傳輸有效像素數(shù)據(jù)。
2.像素傳輸:在HREF高電平期間,每個PCLK周期傳輸一個像素數(shù)據(jù)。
3.行結(jié)束:HREF從高電平變?yōu)榈碗娖?,?biāo)志一行數(shù)據(jù)傳輸完成。
4.像素數(shù)據(jù)周期:ov5640 DVP每個有效數(shù)據(jù)為8位,數(shù)據(jù)采集時需要根據(jù)輸出格式進(jìn)行調(diào)整,輸出RGB565格式需要兩個像素時鐘才能完成傳輸,先傳輸高8位,后第8位。
(2)場時序
1.同步脈沖:VSYNC產(chǎn)生高電平脈沖(取決于極性,ov5640為高)表示新一幀開始。
2.有效數(shù)據(jù)期:新一幀開始一段時間后,每行數(shù)據(jù)通過HSYNC或HREF信號同步。
3.幀結(jié)束:一幀數(shù)據(jù)傳輸完成后,VSYNC再次產(chǎn)生脈沖,標(biāo)志下一幀的開始。
二、Verilog 實現(xiàn)
(1)設(shè)計要求
1. 對 ov5640 輸出RGB565格式的圖像數(shù)據(jù)進(jìn)行接收
2. 接收數(shù)據(jù)輸出給存儲器(如rom、fifo、ddr)進(jìn)行存儲,包含必要輸出端口
(2)設(shè)計要點
1. 場同步:每當(dāng) vsync 產(chǎn)生一次上升沿即代表新一幀的開始(上升沿通過打拍判斷)
2. 行同步:href 的每段高電平代表一行有效數(shù)據(jù)
3. 數(shù)據(jù)格式:一個pclk像素時鐘傳8位,而RGB565一個像素16位,需要兩個pclk像素時鐘才傳輸完一個像素數(shù)據(jù),因此需要進(jìn)行先緩存高8位數(shù)據(jù),并在接收第8位時拼接數(shù)據(jù)并輸出
4. 數(shù)據(jù)有效信號:高電平時代表當(dāng)前RGB565數(shù)據(jù)有效,可供后續(xù)存儲器作寫使能使用
(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, //攝像頭像素時鐘
input wire ov5640_href, //攝像頭行同步信號
input wire ov5640_vsync, //攝像頭場同步信號
input wire [7:0] ov5640_data, //攝像頭場數(shù)據(jù)輸入
output reg [15:0] RGB565_data, //圖像數(shù)據(jù)輸出(RGB565格式)
output wire data_valid //數(shù)據(jù)有效信號(給存儲器的寫使能信號)
);
reg pix_flag; //一像素數(shù)據(jù)結(jié)束標(biāo)志位
wire pic_flag; //一幀圖像結(jié)束標(biāo)志位
reg pic_valid; //幀有效標(biāo)志位
reg [3:0] pic_cnt; //幀計數(shù)器
reg [7:0] r_ov5640_data; //輸入數(shù)據(jù)緩存
reg ov5640_vsync_delay; //場同步信號打拍
reg pix_flag_delay; //一像素數(shù)據(jù)結(jié)束標(biāo)志位打拍
//***************************** 場同步 ****************************//
//場同步信號打拍(用于檢測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;
//前幾幀計數(shù),計滿產(chǎn)生幀有效信號
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
//一像素數(shù)據(jù)結(jié)束標(biāo)志位打拍(用于產(chǎn)生像素數(shù)據(jù)有效信號)
always@(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
pix_flag_delay <= 1'b0;
else
pix_flag_delay <= pix_flag;
//像素數(shù)據(jù)有效信號
assign data_valid = pic_valid & pix_flag_delay;
endmodule
(4)仿真代碼
仿真就是給DVP模塊模擬ov5640產(chǎn)生的圖像數(shù)據(jù),我用的deepseek寫了一版,但經(jīng)過測試發(fā)現(xiàn)不能直接使用,于是根據(jù)它的框架自己進(jìn)行了一些修改,可以通過參數(shù)設(shè)置模擬圖像數(shù)據(jù)的參數(shù)(仿真多少幀、一幀多少行、一行多少像素)。以下模擬輸出了10幀、一幀8行數(shù)據(jù)、一行16個像素點,同時DVP舍去前3幀圖像數(shù)據(jù)。
`timescale 1ns / 1ps
module DVP_data_gen_tb();
reg pclk; //像素時鐘 (10ns周期)
reg rst_n; //復(fù)位信號 (低電平有效)
reg vsync; //場同步信號
reg href; //行同步信號
reg [7:0] data; //像素數(shù)據(jù) (8bit)
wire data_valid; //數(shù)據(jù)有效信號
wire [15:0] RGB565_data; //輸出RGB565格式數(shù)據(jù) (16bit)
//模擬OV5640視頻數(shù)據(jù)生成
parameter WIDTH = 16, //寬(一行多少個像素)
HIGTH = 8, //高(一幀多少行數(shù)據(jù))
FRAME = 10; //幀(模擬發(fā)送多少幀數(shù)據(jù))
integer pixel_cnt = 0, //像素計數(shù)器
row_cnt = 0, //行計數(shù)器
frame_cnt = 0; //幀計數(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
//******************************************模擬場同步信號 (VSYNC)
if (pixel_cnt == 0 && row_cnt == 0) begin
vsync <= 1; // 一幀開始,VSYNC拉高一個時鐘周期
end else begin
vsync <= 0; // VSYNC拉低
end
//******************************************模擬行同步信號 (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; //像素數(shù)據(jù)每次自增1
pixel_cnt <= pixel_cnt + 1;
end else begin
//一行結(jié)束
href <= 0; //HREF低電平表示行結(jié)束
pixel_cnt <= 0;
row_cnt <= row_cnt + 1; //行計數(shù)器加1
end
end
end else begin//一幀結(jié)束
href <= 0;
data <= 0;
row_cnt <= 0; //重置行計數(shù)器
frame_cnt <= frame_cnt + 1; //幀計數(shù)器加1
end
//******************************************模擬FRAME幀后結(jié)束測試
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ù),同時data_valid在前三幀保持為0,后面才開始變化,說明前三幀數(shù)據(jù)被成功舍去。
一幀波形:1幀包含8行,1行有16個8位數(shù)據(jù)。
一行波形:一個RGB565像素數(shù)據(jù)對應(yīng)兩個8位數(shù)據(jù),可以看到每接收2個數(shù)據(jù)就相應(yīng)拼接輸出1個RGB565數(shù)據(jù),同時data_valid數(shù)據(jù)有效信號與數(shù)據(jù)同步產(chǎn)生。
-
FPGA
+關(guān)注
關(guān)注
1645文章
22050瀏覽量
618625 -
接口
+關(guān)注
關(guān)注
33文章
9005瀏覽量
153772 -
圖像傳感器
+關(guān)注
關(guān)注
68文章
1981瀏覽量
130743 -
Verilog
+關(guān)注
關(guān)注
29文章
1367瀏覽量
112300 -
VGA
+關(guān)注
關(guān)注
5文章
572瀏覽量
64644
原文標(biāo)題:基于FPGA的DVP接口實現(xiàn)
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設(shè)計論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
【FPGA設(shè)計實例】FPGA接口實現(xiàn)文本液晶顯示模塊
學(xué)fpga的內(nèi)部結(jié)構(gòu)和各接口實驗怎么學(xué)
基于FPGA的腦機接口實時系統(tǒng)設(shè)計
如果不使用FPGA自帶的SERDES,可否適用LVDS接口實現(xiàn)其功能?
通過USB接口實現(xiàn)FPGA 的SelectMap配置
基于JTAG接口實現(xiàn)ARM的FPGA在線配置設(shè)計

ARM與FPGA的接口實現(xiàn)的解析

基于FPGA的SDRAM串口實驗

C#-Interface接口實現(xiàn)

基于XML語言描述的接口實現(xiàn)方法

評論