關於FPGA的VGA簡易操作
使用FPGA對VGA的操作
在使用FPGA對VGA進行操作時,VGA含有五個有用的訊號,場同步訊號和行同步訊號,RGB三個模擬訊號。行同步訊號主要控制重新整理一行訊號所需要的時間,而場同步訊號用來控制重新整理一次螢幕所需要的時間,RGB提供每個畫素點的顏色。
其簡單顯示程式碼如下
module vgaphoto(
clk, //主控時鐘訊號為50Mhz
rst_n, //主控復位訊號
VGA_R, //輸出VGA的R色彩
VGA_G, //輸出VGA的G色彩
VGA_B, //輸出
VGA_H_SYNC, //輸出VGA的行同步訊號
VGA_V_SYNC, //輸出VGA的場同步訊號
);
///*使用800X600的畫素,重新整理頻率為60Hz,其時鐘頻率為50Mhz,行為1039幀,列為687幀*/
input clk,rst_n; //控制訊號
output [3:0] VGA_G,VGA_B,VGA_R; //VGA輸出的RGB訊號
output VGA_H_SYNC,VGA_V_SYNC; //VGA輸出控制訊號
reg [3:0] VGA_R; //線型的紅色訊號
reg [3:0] VGA_G; //線型的綠色色訊號
reg [3:0] VGA_B; //線型的藍色訊號
//reg VGA_H_SYNC; //暫存器型的行控制訊號
//reg VGA_V_SYNC; //暫存器型的場控制訊號
parameter VGA_H_TOTAL = 1039; //行總的畫素點
parameter VGA_H_DISPLAY = 665; //行顯示畫素點
parameter VGA_H_HIDE = 239; //行隱藏畫素點
parameter VGA_H_STARTBLACK =187; //行前端隱藏畫素點
parameter VGA_H_ENDBLACK = 52; //行後端隱藏畫素點
parameter VGA_V_TOTAL = 687; //列總的畫素點
parameter VGA_V_DISPLAY = 600; //列顯示畫素點
parameter VGA_V_HIDE = 87; //列隱藏畫素點
parameter VGA_V_STARTBLACK = 31; //列前端隱藏畫素點
parameter VGA_V_ENDBLACK = 56; //列前端隱藏畫素點
//時鐘的配置,由50Mhz的時鐘變為40Mhz的時鐘---------------------
//液晶螢幕上計數的座標----------------------------------------
reg[10:0] x_cnt;
reg[9:0] y_cnt;
always @(posedge clk or negedge rst_n) //關於行座標的執行
begin
if(!rst_n) x_cnt <= 11'd0;
else if(x_cnt == 11'd1039) x_cnt <= 10'd0;
else x_cnt <= x_cnt + 1'b1;
end
always @(posedge clk or negedge rst_n) //關於列座標的執行
begin
if(!rst_n) y_cnt <= 10'd0;
else if(y_cnt == 10'd665) y_cnt <= 10'd0;
else if(x_cnt == 11'd1039) y_cnt <= y_cnt + 1'b1;
end
//----------------------------------------------------------------
//液晶的有效顯示區--------------------------------------------------
wire valid; //有效顯示區域
assign valid = (x_cnt >= 11'd187)&&(x_cnt <11'd987)&&(y_cnt >= 10'd31)&&(y_cnt < 10'd631);
wire[9:0] xpos,ypos;
assign xpos = x_cnt - 11'd187;
assign ypos = y_cnt - 10'd31;
//------------------------------------------------------------------
//同步訊號的產生-----------------------------------------------------
reg hsync_r,vsync_r;
always @(posedge clk or negedge rst_n) //同步行訊號的產生
begin
if(!rst_n) hsync_r <= 1'b1;
else if(x_cnt == 11'd0) hsync_r <= 1'b0;
else if(x_cnt == 11'd120) hsync_r <= 1'b1;
end
always @(posedge clk or negedge rst_n) //同步列訊號的產生
begin
if(!rst_n) vsync_r <= 1'b1;
else if(y_cnt == 10'd0) vsync_r <= 1'b0;
else if(y_cnt == 10'd6) vsync_r <= 1'b1;
end
assign VGA_H_SYNC = hsync_r;
assign VGA_V_SYNC = vsync_r;
//-------------------------------------------------------------------
//色彩和掃描點同步---載入圖片--------------------------------------------
reg[4:0] address1;
reg[4:0] address2;
reg[4:0] address3;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
address1 <= 1'b0;
address2 <= 4'b1111;
address3 <= 4'b1010;
end
else if((valid == 1'b1)&&(xpos >= 1'b0)&&(ypos >= 0))
begin
VGA_R <= address1;
VGA_G <= address2;
VGA_B <= address3;
address1 <= address1 + 1'b1;
address2 <= address1 + 2'b11;
address3 <= address1 + 3'b110;
end
else if((xpos >= 9'd800)&&(ypos >= 9'd600))
begin
address1 <= 1'b0;
address2 <= 4'b1111;
address3 <= 4'b1010;
end
end
endmodule