vgaWord文件下载.docx
《vgaWord文件下载.docx》由会员分享,可在线阅读,更多相关《vgaWord文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
=cnt1+1;
ENDPROCESS;
end;
-------------------------------------
--Title:
VGA彩条发生器--
--Author:
Panhongtao--
--Data:
2006-10-1--
-------------------------------------
entityvgadatais
port(Clk:
--时钟信号
Key:
--模式选择
HS,VS:
bufferstd_logic;
--行同步和场同步
R,G,B:
outstd_logic--颜色输出
endvgadata;
architecturebehaveofvgadatais
signalfclk,cclk:
std_logic;
signalmmd:
std_logic_vector(1downto0);
--modeselect
signalfs:
std_logic_vector(3downto0);
signalcc:
std_logic_vector(4downto0);
--HorizontalSynchronization
signalll:
std_logic_vector(8downto0);
--VerticalSynchronization
signalgrbx:
std_logic_vector(2downto0);
--horizontalstripofX
signalgrby:
--verticalstripofY
signalgrbp:
signaldelay:
std_logic_vector(15downto0);
begin
B<
=grbp(0)andHSandVS;
R<
=grbp
(1)andHSandVS;
G<
=grbp
(2)andHSandVS;
process(Clk)--modeofstripgeneration
if(Clk'
eventandClk='
)then
if(Key='
if(delay<
60000)then
delay<
=delay+1;
endif;
else
="
0000000000000000"
if(delay=10000andmmd<
3)then
mmd<
=mmd+1;
elsif(mmd=3)then
00"
endprocess;
process(mmd)
casemmdis
when"
=>
grbp<
=grbx;
--choosehorizontalstrip
01"
=grby;
--chooseverticalstrip
10"
=grbxxorgrby;
--choosetessellateddesignation
whenothers=>
000"
endcase;
process(Clk)
)then--12MHzclocksignaldevidedby13
if(fs=12)then
fs<
0000"
=fs+1;
fclk<
=fs(3);
process(fclk)
if(fclk'
eventandfclk='
if(cc=29)then
cc<
00000"
=cc+1;
cclk<
=cc(4);
process(cclk)
if(cclk'
eventandcclk='
if(ll=481)then
ll<
000000000"
=ll+1;
if(cc>
23)then
HS<
--horizontalsynchronization
if(ll>
479)then
VS<
--verticalsynchronization
if(cc<
grbx<
111"
elsif(cc<
6)then
110"
9)then
101"
12)then
100"
15)then
011"
18)then
010"
21)then
001"
if(ll<
60)then
grby<
elsif(ll<
120)then
180)then
240)then
300)then
360)then
420)then
endbehave;
最近一直在玩转自己板子上的VGA模块,前几天做了一个基于Verilog的VGA显示控制,拿出来和大家分享一下。
一、VGA时序
下面的图是本人画了一个晚上的结果,个人认为能够比较详细的阐述VGA的信号时序。
VGA的时序根据不同的显示分辨率和刷新频率会有变化,具体各种类型的时序信息可以参考下面的网站,这里非常详细的说明的每一种显示模式的VGA时序信息。
二、VGA电平
VSYNC,HSYNC为标准TTL电平,0V~3.3V。
RGB的电平在0V~0.7V之间(0V为黑色,0.7V为全色)。
三、程序顶层框图
VGA产生行同步(HSYNC),场同步信号(VSYNC),并产生每个像素的地址输入单口ROM(显存)中,ROM输出该点需要显示的颜色值。
四、单口ROM(显存)设计
程序的显示模式为800*600,72Hz刷新频率,像素频率为50MHz。
每个像素需要显示的颜色存储在单口RAM中,每种颜色用8个字节表示,则如果要显示800*600分辨率,则需要800*600字节(480KB)的单口ROM,由于FPGA内部没有这么大的RAM(我用的是ep2c8),因此我把屏幕上100*100个像素组成的矩形作为一个逻辑像素(即显示同一种颜色),这样只要8*6字节(48字节),用FPGA自带的RAM是很容易实现的。
ROM中颜色存储地址表
将全屏划分成8*6的方格,每个方格的颜色存储在ROM中,VGA控制器不断产生行坐标(ROM水平地址)和场坐标(ROM垂直地址),最后组合成ROM实际地址输入ROM中,ROM输出该地址的颜色值,显示在LCD中。
五、程序设计
VGA控制器程序
moduleVGA(clk,rst_n,hsync,vsync,vga_r,vga_g,vga_b);
inputclk;
//50MHz
inputrst_n;
//复位信号
outputhsync;
//行同步信号
outputvsync;
//场同步信号
//R、G、B信号输出
output[1:
0]vga_r;
output[2:
0]vga_g;
0]vga_b;
//--------------------------------------------------
reg[10:
0]x_cnt;
//行坐标(这里包括了行同步、后沿、有效数据区、前沿)
reg[9:
0]y_cnt;
//列坐标(这里包括了场同步、后沿、有效数据区、前沿)
reg[5:
0]Xcoloradd;
reg[2:
0]Ycoloradd;
parameter
Left=184,
PixelWidth=100,
Top=29;
always@(posedgeclkornegedgerst_n)
if(!
rst_n)x_cnt<
=10'
d0;
elseif(x_cnt==11'
d1040)x_cnt<
//行计数记到1040
elsex_cnt<
=x_cnt+1'
b1;
always@(posedgeclkornegedgerst_n)//产生行地址(ROM水平地址)
rst_n)Xcoloradd<
=6'
b000000;
elseif(x_cnt>
=Left&
&
x_cnt<
Left+PixelWidth)Xcoloradd<
=Left+PixelWidth&
Left+2*PixelWidth)Xcoloradd<
b000001;
=Left+2*PixelWidth&
Left+3*PixelWidth)Xcoloradd<
b000010;
=Left+3*PixelWidth&
Left+4*PixelWidth)Xcoloradd<
b000011;
=Left+4*PixelWidth&
Left+5*PixelWidth)Xcoloradd<
b000100;
=Left+5*PixelWidth&
Left+6*PixelWidth)Xcoloradd<
b000101;
=Left+6*PixelWidth&
Left+7*PixelWidth)Xcoloradd<
b000110;
=Left+7*PixelWidth&
Left+8*PixelWidth)Xcoloradd<
b000111;
elseXcoloradd<
b110000;
//背景颜色地址
rst_n)y_cnt<
elseif(y_cnt==10'
d666)y_cnt<
//场同步记到666
d1040)y_cnt<
=y_cnt+1'
//每计数完一行,场同步就加一
always@(posedgeclkornegedgerst_n)//产生列地址(ROM垂直地址)
rst_n)Ycoloradd<
=3'
b000;
elseif(y_cnt>
=Top&
y_cnt<
Top+PixelWidth)Ycoloradd<
=Top+PixelWidth&
Top+2*PixelWidth)Ycoloradd<
b001;
=Top+2*PixelWidth&
Top+3*PixelWidth)Ycoloradd<
b010;
=Top+3*PixelWidth&
Top+4*PixelWidth)Ycoloradd<
b011;
=Top+4*PixelWidth&
Top+5*PixelWidth)Ycoloradd<
b100;
=Top+5*PixelWidth&
Top+6*PixelWidth)Ycoloradd<
b101;
elseYcoloradd<
b110;
//signalportROM
wire[7:
0]color;
wire[5:
0]coloradd;
assigncoloradd={Ycoloradd,3'
b000}|Xcoloradd;
//将水平地址和垂直地址合成ROM实际地址
spromu1(coloradd,clk,color);
//---------------------------------------------------
wirevalid;
//有效数据显示区标志,就是你在液晶屏幕上可以看到的区域
assignvalid=(x_cnt>
10'
d184)&
(x_cnt<
d984)
&
(y_cnt>
d29)&
(y_cnt<
d629);
reghsync_r,vsync_r;
if(!
rst_n)begin
hsync_r<
=1'
b0;
vsync_r<
end
elsebegin
=x_cnt>
d120;
//产生hsync信号(行同步)whenx_cnt>
=50,thenhsync_r=1,else0;
低电平同步
=y_cnt>
d6;
//产生vsync信号(场同步)myLCDislowsync
assignhsync=hsync_r;
assignvsync=vsync_r;
//--------------------------------------------------
//颜色输出
assignvga_r[1]=valid?
color[7]:
1'
assignvga_r[0]=valid?
color[6]:
assignvga_g[2]=valid?
color[5]:
assignvga_g[1]=valid?
color[4]:
assignvga_g[0]=valid?
color[3]:
assignvga_b[2]=valid?
color[2]:
assignvga_b[1]=valid?
color[1]:
assignvga_b[0]=valid?
color[0]:
endmodule
这次程序中只在ROM中存储了一些随机的数,因此显示出来是一些小方格,如果ROM做的更大,完全可以存储一幅图像,显示在LCD中。
不过由于由于用ROM做为显存,每次只能显示一幅静态的图像,而且没有加入字符库,不能显示字符,在下次的文章中,我将使用双口RAM,加上NiosII处理器,这样可以方便的显示各种字符。