引言:本文我們介紹利用FPGA實(shí)現(xiàn)VGA圖像顯示,主要介紹VGA硬件接口、VGA接口時(shí)序原理以及FPGA代碼實(shí)現(xiàn)VGA接口時(shí)序、仿真等內(nèi)容。
01、VGA硬件接口介紹
VGA(Video Graphics Array)視頻圖形陣列是IBM于1987年提出的一個(gè)使用模擬信號(hào)的電腦顯示標(biāo)準(zhǔn)。VGA接口即電腦采用VGA標(biāo)準(zhǔn)輸出數(shù)據(jù)的專用接口。VGA接口共有15針,分成3排,每排5個(gè)孔,顯卡上應(yīng)用最為廣泛的接口類型,絕大多數(shù)顯卡都帶有此種接口。它傳輸紅、綠、藍(lán)模擬信號(hào)以及同步信號(hào)(水平和垂直信號(hào))。
圖1、VGA接口
管腳 | 信號(hào) | 信號(hào)描述 |
1 | RED | 紅基色 |
2 | GREEN | 綠基色 |
3 | BLUE | 藍(lán)基色 |
4 | ADDR_CODE | 地址碼 |
5 | RES | 自測(cè)試(各家定義不同) |
6 | RED_GND | 紅地 |
7 | GREEN_GND | 綠地 |
8 | BLUE_GND | 藍(lán)地 |
9 | RES | 保留(各家定義不同) |
10 | DIG_GND | 數(shù)字地 |
11 | ADDR_CODE | 地址碼 |
12 | ADDR_CODE | 地址碼 |
13 | HS | 行同步信號(hào) |
14 | VS | 場(chǎng)同步信號(hào) |
15 | ADDR_CODE | 地址碼 |
常見的VGA分辨率如圖2所示。
圖2、常見的VGA分辨率
02、VGA接口時(shí)序及顯示原理
VGA顯示主要取決于R、G、B三基色,也即三原色。根據(jù)R、G、B位寬的不同,VGA顯示的效果也不同,常見有24bit(R/G/B各8bit)、16bit(R 5bit、G 6bit、B 6bit)、12bit(R/G/B各4bit)。
對(duì)于分辨率600×400@60Hz,該參數(shù)顯示的是VGA有效數(shù)據(jù)參數(shù),即VGA顯示刷新率60幀,每幀600×400個(gè)像素點(diǎn)。VGA接口實(shí)際傳輸?shù)臄?shù)據(jù)比此數(shù)值要大。
VGA顯示器逐行掃描原理:逐行掃描是掃描從屏幕左上角一點(diǎn)開始,從左至右逐點(diǎn)掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置。在這期間,CRT對(duì)電子束進(jìn)行消隱,每行結(jié)束時(shí),用行同步信號(hào)HS進(jìn)行同步;當(dāng)掃描完所有的行,形成一幀,用場(chǎng)同步信號(hào)VS進(jìn)行幀同步,并使掃描回到屏幕左上方,同時(shí)進(jìn)行場(chǎng)消隱,開始下一幀。
從逐行掃描的原理中,我們可以了解,當(dāng)一行掃描完成后,切換到下一行時(shí),需要行同步信號(hào)及行消隱時(shí)間;當(dāng)一幀掃描完成后,切換到下一幀時(shí),需要場(chǎng)同步信號(hào)及場(chǎng)消隱時(shí)間,這樣就形成了VGA掃描時(shí)序,如圖3所示。
圖3、VGA行場(chǎng)時(shí)序圖
如圖3所示,Sync為同步信號(hào),Back Porch為顯示后肩時(shí)間,Active Video為有效視頻,F(xiàn)ront Porch為顯示前肩時(shí)間。Sync+Back Porch+Active Video+Front Porch構(gòu)成一個(gè)完整行周期。
圖4、VGA圖像幀定義
圖4定義了一幀圖像的時(shí)序定義。圖中場(chǎng)信號(hào)的定義與行信號(hào)定義類似。行信號(hào)以像素點(diǎn)為單位,場(chǎng)信號(hào)以行為單位。VGA圖像時(shí)序的編寫即是對(duì)圖4中各個(gè)時(shí)序段進(jìn)行定時(shí)。
03、VGA接口時(shí)序關(guān)鍵代碼編寫
下面以1920×1080@60Hz分辨率介紹VGA時(shí)序定義。在VESA表準(zhǔn)中給出了該分辨率的參數(shù)定義,如圖5所示。
圖5、1920×1080@60Hz分辨率圖像參數(shù)
在圖5中,需要注意藍(lán)色標(biāo)記的HS/VS信號(hào)極性,這在VESA標(biāo)準(zhǔn)中有規(guī)定要求,圖3只是給出了其中一種HS/VS信號(hào)極性,其他3種請(qǐng)參考VESA標(biāo)準(zhǔn)。
根據(jù)圖5所示,我們需要關(guān)注的參數(shù)如圖中各個(gè)顏色標(biāo)記所示。
`ifdef VIDEO_1920_1080 //一幀圖像參數(shù)定義
//行周期參數(shù)定義
parameter H_ACTIVE = 1920;// 行數(shù)據(jù)有效像素點(diǎn)數(shù)
parameter H_FRONT_PORCH = 88; // 行消隱前肩像素點(diǎn)數(shù)
parameter H_SYNC_TIME = 44; // 行同步信號(hào)像素點(diǎn)數(shù)
parameter H_BACK_PORCH = 148; // 行消隱后肩像素點(diǎn)數(shù)
//場(chǎng)周期參數(shù)定義
parameter V_ACTIVE = 1080;// 場(chǎng)數(shù)據(jù)有效像素點(diǎn)數(shù)
parameter V_FRONT_PORCH = 4; // 場(chǎng)消隱前肩像素點(diǎn)數(shù)
parameter V_SYNC_TIME = 5; // 場(chǎng)同步信號(hào)像素點(diǎn)數(shù)
parameter V_BACK_PORCH = 36; // 場(chǎng)消隱后肩像素點(diǎn)數(shù)
`endif
根據(jù)一幀圖像參數(shù)定義,進(jìn)一步定義行、場(chǎng)掃描計(jì)數(shù)器,這兩個(gè)計(jì)數(shù)器可以用來產(chǎn)生HS行同步信號(hào)、VS場(chǎng)同步信號(hào)、圖像有效數(shù)據(jù)使能信號(hào)DE以及圖像有效數(shù)據(jù)坐標(biāo)。
parameter H_TOTAL_TIME = H_ACTIVE + H_FRONT_PORCH + H_SYNC_TIME + H_BACK_PORCH;
parameter V_TOTAL_TIME = V_ACTIVE + V_FRONT_PORCH + V_SYNC_TIME + V_BACK_PORCH;
//行掃描計(jì)數(shù)器
always@(posedge i_clk) begin
if(h_syn_cnt >= H_TOTAL_TIME-1) h_syn_cnt <= 0;
else h_syn_cnt <= h_syn_cnt + 1;
end
// 場(chǎng)掃描計(jì)數(shù)器
always@(posedge i_clk) begin
if(h_syn_cnt >= H_TOTAL_TIME-1) begin
if(v_syn_cnt >= V_TOTAL_TIME-1)
v_syn_cnt <= 0;
else
v_syn_cnt <= v_syn_cnt + 1;
end
end
HS行同步信號(hào)、VS場(chǎng)同步信號(hào)Verilog代碼。
// 行同步信號(hào)
always@(posedge i_clk) begin
if(h_syn_cnt < H_SYNC_TIME)
o_hsyn <= 0;
else
o_hsyn <= 1;
end
// 場(chǎng)同步信號(hào)
always@(posedge i_clk) begin
if(v_syn_cnt < V_SYNC_TIME)
o_vsyn <= 0;
else
o_vsyn <= 1;
end
圖像有效數(shù)據(jù)使能信號(hào)DE。
//有效數(shù)據(jù)使能信號(hào)DE
always@(posedge i_clk) begin
if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
begin
if(h_syn_cnt >= H_SYNC_TIME + H_BACK_PORCH && h_syn_cnt < H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE)
o_en_pos <= 1;
else
o_en_pos <= 0;
end
else
o_en_pos <= 0;
end
圖像有效數(shù)據(jù)坐標(biāo)產(chǎn)生x_pose、y_pose。
//x坐標(biāo)數(shù)據(jù)
always@(posedge i_clk) begin
if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
begin
if(h_syn_cnt >= H_SYNC_TIME + H_BACK_PORCH && h_syn_cnt < H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE)
o_x_pos <= h_syn_cnt - (H_SYNC_TIME + H_BACK_PORCH);
else
o_x_pos <= 0;
end
else
o_x_pos <= 0;
end
//y坐標(biāo)數(shù)據(jù)
always@(posedge i_clk) begin
if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
o_y_pos <= v_syn_cnt - (V_SYNC_TIME + V_BACK_PORCH);
else
o_y_pos <= 0;
end
04、FPGA工程實(shí)現(xiàn)框架
FPGA實(shí)現(xiàn)VGA顯示功能框架如圖6所示。
圖6、FPGA實(shí)現(xiàn)VGA顯示功能框圖
如圖6所示,整個(gè)工程由四個(gè)模塊組成:PLL模塊、vga_timing_ctrl模塊、video_source模塊和hdmi_interface_dir模塊。由于實(shí)驗(yàn)電路板上沒有VGA接口,因此采用HDMI接口實(shí)現(xiàn)最終圖像顯示。圖中video_source輸出的信號(hào)可以直接送入視頻DAC芯片,如ADV7123實(shí)現(xiàn)VGA圖像顯示。
PLL模塊:產(chǎn)生VGA圖像像素時(shí)鐘pixclk和pixclk_x5時(shí)鐘(HDMI接口串行時(shí)鐘);
vga_timing_ctrl模塊:實(shí)現(xiàn)VGA時(shí)序產(chǎn)生和控制;
video_source模塊:產(chǎn)生VGA圖像數(shù)據(jù);
hdmi_interface_dir模塊:實(shí)現(xiàn)HDMI接口驅(qū)動(dòng)功能。
05、Modelsim軟件仿真與測(cè)試
編寫Testbench測(cè)試文件,功能仿真如圖7所示。
圖7、VGA時(shí)序Modelsim仿真
06、硬件測(cè)試與驗(yàn)證
硬件平臺(tái):XC7Z035FFG676-2
Vivado軟件:2017.4
工程編譯完成后,下載bit文件到電路板,測(cè)試結(jié)果如圖所示。
圖、VGA時(shí)序圖像顯示
歡迎關(guān)注FPGA技術(shù)實(shí)戰(zhàn)公眾號(hào),喜歡就多多轉(zhuǎn)發(fā)吧!