基于DE1开发板的VGA图像显示.docx
《基于DE1开发板的VGA图像显示.docx》由会员分享,可在线阅读,更多相关《基于DE1开发板的VGA图像显示.docx(33页珍藏版)》请在冰点文库上搜索。
基于DE1开发板的VGA图像显示
题目基于DE1开发板的VGA图像显示
一简介
1功能简介
VGA(VideoGraphicsArray)是IBM在1987年随PS/2机一起推出的一种视频传输标准,具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。
本设计是基于altera公司的Development&EducationBoard1上的VGA接口开发的一个图形显示模块。
通过VGA协议,可以在显示屏上显示分辨率为640*480,刷新频率为60Hz的彩条及彩色图片。
图片数据可以从24bit宽的bmp图像通过一个C程序来转化成需要的格式。
本设计可以通过alteraDE1自带的软件来把图片数据下载到sram里,也可以通过串口把数据下载到sram里。
2用途
该模块可以用于显示器工厂里对显示屏的坏点检测,也可以在大屏幕上显示需要的图像信息,由于系统简单,可扩展性好,图像更新方便,比传统用PC机控制的方法有成本上的极大优势。
并且可以通过加大像素同步信号的频率或者并联几个同样的显示模块来达到控制更大显示屏的目的,有极大的灵活性。
3难度部分
本设计的难度部分主要在图像产生模块与串口通信模块两部分,在图像产生模块里完成了对ram里压缩格式数据的解压缩,否则未压缩的数据无法完全放到sram里。
串口通信模块在开始信号捕捉,数据计数以及数据和时钟的同步上逻辑关系不太好处理,特别是一个进程里只能捕捉一个时钟沿信号,并且对同一信号的赋值只能在同一个进程里,这样就造成捕捉到起始信号的下降沿后无法直接对数据进行计数,只能通过标志位传递来进行同步。
4创新部分
创新部分在于串口通信模块没有采用常用的状态机加移位寄存器的结构,而是采用直接对号入座的方法,便于对接收到的数据进行变换,使软件和硬件可以共同完成数据的编码解码,增加了系统的灵活性。
二设计思路
1系统整体结构
系统的整体结构如图所示,本电路包含7个模块。
像素时钟产生模块(pixel),同步信号产生模块(sync),显示控制模块(control),图像产生模块(picture_style),数码管显示模块(hex_display),串口通信模块(RS232_RXD),端口选择模块(sram_latch)。
图1系统整体结构
像素时钟产生模块由系统时钟50MHz分频出25MHz的像素时钟。
同步信号产生模块用来产生VGA相关的行同步时钟,场同步时钟以及奇偶场同步信号。
显示控制模块定义了两种切换图片的模式,即手动模式和自动模式。
图像产生模块里定义了8种显示图像,有从sram里读取的,也有直接产生的。
通过计数,循环显示8种图片。
数码管显示模块用来在数码管上显示图片的计数。
串口通信模块完成与PC通过串口向sram下载图片的功能。
端口选择模块用来对sram的数据源和地址源进行选取。
顶层实体的端口定义如下。
entityvgais
port(
CLOCK_50:
instd_logic;
KEY3:
instd_logic;
SW0:
instd_logic;
VGA_R:
outstd_logic_vector(3downto0);
VGA_G:
outstd_logic_vector(3downto0);
VGA_B:
outstd_logic_vector(3downto0);
VGA_HS:
outstd_logic;
VGA_VS:
outstd_logic;
rxd:
instd_logic;
mode:
instd_logic;
SRAM_ADDR:
bufferstd_logic_vector(17downto0);
SRAM_DQ:
inoutstd_logic_vector(15downto0);
HEX0:
outstd_logic_vector(6downto0);
LEDG:
outstd_logic_vector(7downto0);
LEDR:
outstd_logic_vector(9downto0);
SRAM_WE_N,
SRAM_OE_N,
SRAM_UB_N,
SRAM_LB_N,
SRAM_CE_N:
outstd_logic
);
endentity;
其中,CLOCK_50为时钟输入引脚,输入50MHz的时钟信号作为系统时钟。
KEY3按键是手动切换按钮,每按一次就切换一次画面。
SW0开关是自动/手动切换开关,高电平时自动定时切换画面,低电平是用KEY3来控制切换。
VGA_R,VGA_G和VGA_B为RGB数据输入端,每个均为4位宽。
VGA_HS是行同步信号。
mode为工作模式选择端口,高电平时通过串口通信向sram里写数据,低电平时通过VGA在屏幕上显示图像。
由FPGA按VGA时序产生。
同理VGA_VS是场同步信号。
rxd是RS232串口通信的接收端,SRAM_ADDR为与sram相连的18位地址总线,可0到512K随机寻址。
SRAM_DQ为16位数据总线,给出地址后就可以在数据总线上直接进行读写。
SRAM_WE_N,SRAM_OE_N,SRAM_UB_N,SRAM_LB_N和SRAM_CE_N为sram的控制总线,均为低电平有效。
根据sram的真值表进行相应的控制,这里由于之需要进行读操作,故除SRAM_WE_N接可控制端,其他都直接接地就可以。
2像素时钟产生模块
图2像素时钟产生模块
根据VGA协议,像素时钟为大约25MHz的信号,故只需对50MHz的系统时钟二分频就能得到。
图3分频仿真图
entitypixelis
port(
CLOCK_50:
instd_logic;
pixel_clk:
outstd_logic
);
end;
architecturearcofpixelis
begin
pixel:
--generate25MHzclock
process(CLOCK_50)
variablepixel_clk_t:
std_logic;
begin
ifCLOCK_50'eventandCLOCK_50='1'then
pixel_clk_t:
=notpixel_clk_t;
endif;
pixel_clk<=pixel_clk_t;
endprocess;
end;
VGA硬件电路
DE1的VGA接口自带电阻阵列进行了简单的DA转换,电路图如图4。
RGB每个通道都是由4位宽的数据来控制,故能够显示16*16*16=4096种颜色,这就使得可以用此电路显示一些颜色相对复杂的图片。
图4VGA模块电路图
VGA协议
VGA的显示协议如图2-2。
要想在屏幕上显示图像,FPGA需要输出VGA需要的3个同步信号,即像素同步,行同步和场同步。
三个信号的时间关系如表2-1所示。
具体来说。
检测到每个像素同步的上升沿时对RGB数据端口的数据进行更新,即输出数据。
行有效期间输出数据,行消隐期间停止输出数据。
场有效期间正常输出数据,场消隐期间必须使RGB输出均为0,行同步信号可以输出,也可以不输出。
这里场消隐区如果有数据输出,就会造成显示器识别不出数据而显示频率超出范围。
行同步和场同步为高电平脉冲和低电平脉冲都可以,因为显示器内部能够自动识别这两种规范,故只要脉冲持续时间及周期对就可以。
图5VGA时序
Parameter
VerticalSync
HorizontalSync
Time
Clocks
Lines
Time
Clocks
Syncpulsetime
416800
521
32us
800
Displaytime
384000
480
640
Pulsewidth
64us
1600
2
96
Frontporch
320us
8000
10
640us
16
Backproch
928us
23200
29
48
表1VGA时序与时钟关系
3同步信号产生模块
图6同步信号产生模块
根据VGA协议,需要通过对像素同步信号计数,产生行同步信号VGA_HS和场同步信号VGA_VS以及奇偶场同步信号VGA_VS_period。
同时,在本模块中也产生一些控制信号。
在pixel进程里从50MHz的系统时钟中分频出25MHz的时钟作为像素同步。
在href进程里通过查像素同步的个数来确定行同步信号。
并为行消隐区不显示数据定义pixel_en信号来进行控制。
在vsync进程里通过查行同步脉冲的个数来确定场同步脉冲。
在scencewait进程中通过查场的个数来确定自动图片切换时间,这里选择每隔60场自动切换一次图片。
图7像素同步信号与行同步信号仿真
图8像素同步信号与行同步信号仿真的局部放大
仿真1显示了像素同步时钟与行同步信号的关系,其中pixel_count是对pixel_clk的计数,当数到31E,即798时,VGA_HS变为高电平,之后又数到96后变为低电平,然后重复,这就产生了行同步信号,href_count是对行同步信号的脉冲计数。
同理,行同步信号与场同步信号之间的关系也是如此。
由于本模块的其他信号时间差距比较大,比如像素时钟为25MHz,而场同步为60Hz,故仿真起来很不方便,所以只是从示波器上观察产生的信号是否正确。
entitysyncis
port(
VGA_HS:
outstd_logic;
VGA_VS:
outstd_logic;
pixel_clk:
instd_logic;
pixel_en:
outstd_logic;
VGA_VS_period:
bufferstd_logic;
href_count:
bufferintegerrange0to525;
pixel_count:
bufferintegerrange0to798;
href_en:
bufferstd_logic
);
end;
architecturearcofsyncis
constanthref_all_dot:
integer:
=798;--800pixeldotsinalineincludingblankingzone
constanthref_sy_dot:
integer:
=96;--hrefhighleveltimeis96dot
constantver_all_line:
integer:
=525;
signalVGA_HS_period:
std_logic;
begin
href:
--generateHsync-highlevelpuls
process(pixel_clk,href_en)
begin
ifpixel_clk'eventandpixel_clk='1'then
ifpixel_countVGA_HS_period<='1';
pixel_en<='0';
elsifpixel_count<144then
VGA_HS_period<='0';
pixel_en<='0';
elsifpixel_count<784then--pixelenablewhen136-784
VGA_HS_period<='0';
pixel_en<='1';
elsifpixel_countVGA_HS_period<='0';
pixel_en<='0';
endif;
ifpixel_count=href_all_dotthen
pixel_count<=0;
elsepixel_count<=pixel_count+1;
endif;
endif;
ifhref_en='0'then
pixel_en<='0';--stoppixelwhenhrefisdisabled
endif;
VGA_HS<=VGA_HS_period;
endprocess;
vsync:
--generateVsync
process(VGA_HS_period)
begin
ifVGA_HS_period'eventandVGA_HS_period='1'then
ifhref_count<2then--pulldownto0whenVsync
VGA_VS_period<='0';
href_en<='0';
elsifhref_count<35then
VGA_VS_period<='1';
href_en<='0';
elsifhref_count<515then
VGA_VS_period<='1';
href_en<='1';--hrefenablewhen35-515
elsifhref_countVGA_VS_period<='1';
href_en<='0';
endif;
ifhref_count=ver_all_linethen
href_count<=0;
elsehref_count<=href_count+1;
endif;
endif;
VGA_VS<=VGA_VS_period;
endprocess;
end;
4显示控制模块
图9显示控制模块
数够60场的时间后auto_picture_count_s产生一个上升沿,按键KEY3按一下产生一个低电平脉冲。
故定义picture_count_s为auto_picture_count_s与KEY3相异或,在Style_control进程里识别picture_count_s的上升沿,每个上升沿到来就让图片计数加一。
这样就能达到既能手动控制又能自动控制的目的。
图10显示控制模块时序仿真
如图,SW0为低电平时是手动模式,此时没按一次KEY3,即KEY3段产生一个低电平脉冲,picture计数加1。
不按KEY3时picture不变。
当SW0为高电平时为自动模式,此时隔一定的时间picture自动加1,并且在自动模式下,每按一次KEY3,picture也加1。
达到了手动与自动相结合控制的目的。
entitycontrolis
port(
VGA_VS_period:
instd_logic;
SW0:
instd_logic;
KEY3:
instd_logic;
picture:
bufferintegerrange0to7
);
end;
architecturearcofcontrolis
signalscence_wait:
std_logic;
signalSW0_t:
std_logic;
signalpicture_count_s:
std_logic;
signalauto_picture_count_s:
std_logic;
begin
scencewait:
--changepictureaftersomescences
process(VGA_VS_period)
variablescence_wait_t:
integerrange0to31;
begin
ifVGA_VS_period'eventandVGA_VS_period='1'then
ifscence_wait_t<30then
scence_wait_t:
=scence_wait_t+1;
elsescence_wait_t:
=0;
scence_wait<=notscence_wait;
endif;
endif;
endprocess;
SW0_t<=SW0;
auto_count_s:
--changepictureafterpushSW0
process(SW0_t,scence_wait)
begin
ifSW0_t='1'then
ifscence_wait'eventandscence_wait='1'then
auto_picture_count_s<=notauto_picture_count_s;
endif;
elseauto_picture_count_s<='1';
endif;
endprocess;
picture_count_s<=auto_picture_count_sxorKEY3;--twowaystocontrol
Style_control:
process(picture_count_s)
begin
ifpicture_count_s'eventandpicture_count_s='1'then
picture<=picture+1;
endif;
endprocess;
end;
5图像产生模块
图11图像产生模块
Picture_style进程是对显示的图片进行控制。
这里定义了8种显示图像,0为自定义的图片;1为纯白;2为纯黑;3为纯红;4为纯绿;5为竖直彩条;6为竖直渐变彩条;7为水平彩条。
每个像素时钟到来时,就按照图片计数里的数字显示相应的图片。
其中第0种情况是读取sram里的数据来进行显示,由于sram的读取时间为10ns,而FPGA的时钟周期为20ns,故可以直接对sram进行读取。
这里用到一个状态机是因为对原始图像数据进行了压缩,把空余的空间也用上了,即用3个存储单元储存4个像素的数据。
故读取的时候需要读三个数据后空一次,并把每次读取的数据跟RGB三个通道对应好。
分辨率是640*480,每个像素由RGB3个分量组成,每个分量由四位二进制数来表示,这样一幅彩色图片在不压缩的情况下要用640*480*12bit,即大约460K字节.所以需要外部存储器来储存图像信息。
开发板上有一片512k字节的sram,并且sram的存取相对简单,故这里用sram作为存储器件。
Sram的硬件连接如图9。
由于sram的数据总线是18位,一个储存单元只放一个像素会空出四位,即加入一个像素的数据为F(R)F(G)F(B),则在sram中储存格式为0FFF。
而且这样用存一张图片要用400k字节的空间,sram无法提供这么大的空间。
故只能考虑对数据进行压缩,即(FFF)(FFF)(FFF)(FFF),用三个存储单元储存4个像素的数据,这就要求在用VHDL实现的时候需要注意以下读取格式。
图12sram硬件连接图
本部分代码比较长,故在附录1中给出。
由于本电路只能显示已经储存在sram里的特定格式的图片,故需要先用自己编写的c程序对bmp格式的图片进行转换,并用altera自带的软件把数据先烧写到sram中。
图像处理的C程序见附录2。
6数码管显示模块
图13数码管显示模块
本模块的作用是把对显示图像的计数用数码管显示出来,即显示0-7。
图14数码管显示模块仿真波形
entityhex_displayis
port(
HEX0:
outstd_logic_vector(6downto0);
CLOCK_50:
instd_logic;
picture:
inintegerrange0to7
);
end;
architectureartofhex_displayis
begin
hex_display:
process(picture,CLOCK_50)
begin
ifCLOCK_50'eventandCLOCK_50='1'then
casepictureis
when0=>HEX0<="1000000";
when1=>HEX0<="1111001";
when2=>HEX0<="0100100";
when3=>HEX0<="0110000";
when4=>HEX0<="0011001";
when5=>HEX0<="0010010";
when6=>HEX0<="0000010";
when7=>HEX0<="1011000";
whenothers=>NULL;
endcase;
endif;
endprocess;
end;
7串口通信模块
图15串口通信模块
该模块的功能是通过串口从PC机上读取图像信息,并把读到的图像数据写到sram里面,以供在图像输出模式时进行读取。
在本模块中,包含一个子模块用于产生波特率为115200的时钟。
由前面可知一个图片的数据量为450Kbyte,而传输速率为115200/10=byte/s,故理想的最小传输时间为450/=39s。
这是用PC机通过串口传输原始格式的图片数据的最小时间。
捕捉rxd端在空闲状态下的下降沿,来识别数据的开始,由于数据传输格式是8位数据,无奇偶校验,一个停止位,故检测到开始信号后经过八个时钟可以读取八位数据,之后就是停止位。
在读到停止位的时候把读到的完整数据写到sram里,由于sram的数据总线宽度为16位,而串口一次只能传8位,故需要连续采集两次然后一起写入sram,模块里的double_done就是用来标志连续采集完两个字节,可以发送的标志位。
LEDG和LEDR总共18个led灯,用来以二进制形式显示写到的地址,可以大体检测传输数量是否正确。
图16串口通信模块SignalTapII分析
上图为用SignalTapII进行逻辑分析的波形图。
用串口工具在rxd端输入0x01,clk为波特率是115200bps的时钟信号。
Data储存串口读到的信号。
Bitcount是对读入的数据位进行计数。
无数据时rxd为高电平,此时模块处于idle状态,当rxd端有数据,首先