以分辨率640*480为例:
要实现VGA显示很简单,只需要注意时序即可,显示分为四个时期,同步期,后隐期,显示期,前隐期。只要完成对应时期的计数,然后把有效显示时期分配各种颜色即可
所以程序分为两大模块:各个有效信号的计数和对应颜色输出的区域
有效信号计数模块:
module sync_module
(
CLK, RSTn,
VSYNC_Sig, HSYNC_Sig, Ready_Sig,
Column_Addr_Sig, Row_Addr_Sig
);
input CLK;
input RSTn;
output VSYNC_Sig;
output HSYNC_Sig;
output Ready_Sig;
output [10:0]Column_Addr_Sig;
output [10:0]Row_Addr_Sig;
reg [10:0]Count_H;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
Count_H <= 11'd0;
else if( Count_H == 11'd800 )
Count_H <= 11'd0;
else
Count_H <= Count_H + 1'b1;
reg [10:0]Count_V;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
Count_V <= 11'd0;
else if( Count_V == 11'd525 )
Count_V <= 11'd0;
else if( Count_H == 11'd800 )
Count_V <= Count_V + 1'b1;
reg isReady;
/*上面两个always 行场总时间的计数 下面always 找出行场均有效的时间段*/
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
isReady <= 1'b0;
else if( ( Count_H > 11'd144 && Count_H < 11'd784 ) &&
( Count_V > 11'd35 && Count_V < 11'd515 ) )
isReady <= 1'b1;
else
isReady <= 1'b0;
assign VSYNC_Sig = ( Count_V <= 11'd2 ) ? 1'b0 : 1'b1;//场同步的时候为零,其余为一,这个是要输出给vga的
assign HSYNC_Sig = ( Count_H <= 11'd96 ) ? 1'b0 : 1'b1;
assign Ready_Sig = isReady;
assign Column_Addr_Sig = isReady ? Count_H - 11'd145 : 11'd0; // Count from 0,也就是行的显示期,只不过让他的计数从零开始
assign Row_Addr_Sig = isReady ? Count_V - 11'd36 : 11'd0; // Count from 0,理由同上,这两个信号就是用来后面模块进行颜色区间分配的
endmodule
颜色分配模块:
module vga_control_module
(CLK, RSTn, Ready_Sig, Column_Addr_Sig, Row_Addr_Sig,data_out );
input CLK;
input RSTn;
input Ready_Sig;
input [10:0]Column_Addr_Sig;
input [10:0]Row_Addr_Sig;
output [15:0]data_out;
/*下面就是各种颜色的定义,原理就是三原色,亮就为1,不亮就为零*/
localparam RED = 16'hF800;
localparam GREEN = 16'h07E0;
localparam BLUE = 16'h001F;
localparam WHITE = 16'hFFFF;
localparam BLACK = 16'h0000;
localparam YELLOW = 16'hFFE0;
localparam CYAN = 16'hF81F;
localparam ROYAL = 16'h07FF;
parameter H_DISP = 11'd640;//这两个信号是用来分配颜色区间的
parameter V_DISP = 10'd480;
reg [15:0]vga_data;
always@(posedge CLK or negedge RSTn)//这里就是颜色分配了,看你自由发挥了
begin
if(!RSTn)
vga_data <= 16'h0;
else
begin
if (Column_Addr_Sig >= 0 && Column_Addr_Sig < (H_DISP>>3)&&Row_Addr_Sig>=0&&Row_Addr_Sig<(V_DISP>>3))
vga_data <= RED;
else if(Column_Addr_Sig >= (H_DISP>>3)&& Column_Addr_Sig < (H_DISP>>3)*2&&Row_Addr_Sig>=(V_DISP>>3)&&Row_Addr_Sig<(V_DISP>>3)*2)
vga_data <= GREEN;
else if(Column_Addr_Sig >= (H_DISP>>3)*2&& Column_Addr_Sig < (H_DISP>>3)*3&&Row_Addr_Sig>=(V_DISP>>3)*2&&Row_Addr_Sig<(V_DISP>>3)*3)
vga_data <= BLUE;
else if(Column_Addr_Sig >= (H_DISP>>3)*3&& Column_Addr_Sig < (H_DISP>>3)*4&&Row_Addr_Sig>=(V_DISP>>3)*3&&Row_Addr_Sig<(V_DISP>>3)*4)
vga_data <= WHITE;
else if(Column_Addr_Sig >= (H_DISP>>3)*4&& Column_Addr_Sig < (H_DISP>>3)*5&&Row_Addr_Sig>=(V_DISP>>3)*4&&Row_Addr_Sig<(V_DISP>>3)*5)
vga_data <= BLACK;
else if(Column_Addr_Sig >= (H_DISP>>3)*5&& Column_Addr_Sig < (H_DISP>>3)*6&&Row_Addr_Sig>=(V_DISP>>3)*5&&Row_Addr_Sig<(V_DISP>>3)*6)
vga_data <= YELLOW;
else if(Column_Addr_Sig >= (H_DISP>>3)*6&& Column_Addr_Sig < (H_DISP>>3)*7&&Row_Addr_Sig>=(V_DISP>>3)*6&&Row_Addr_Sig<(V_DISP>>3)*7)
vga_data <= CYAN;
else// if(vga_xpos >= (H_DISP<<3)*7 && vga_xpos < (H_DISP<<3)*8)
vga_data <= ROYAL;
end
end
assign data_out=vga_data;
endmodule
具体理解都在代码中,在此声明,此博文只是粗略写下自己理解,对读者有没有帮助就不清楚了,具体可以移步http://www.cnblogs.com/crazybingo/archive/2011/07/28/2119948.html