当前位置:文档之家› 基于FPGA的VGA图像显示

基于FPGA的VGA图像显示

基于FPGA的VGA图像显示1、VGA显示原理VGA标准是一种计算机显示标准,最初是由IBM公司在1987 年提出的,分辨率是640*480。

VGA 接口也叫做D_Sub 接口,是显卡上输出模拟信号的接口。

目前大多数计算机与外部显示设备之间都是通过模拟VGA接口连接,计算机内部以数字方式生成的显示图像信息,被显卡中的D/A 转换器转变为R、G、B三原色信号和行、场同步信号,信号通过电缆传输到显示设备中。

常见的彩色显示器一般由阴极射线管(CRT) 构成,彩色由GRB(Green Red Blue) 基色组成。

显示采用逐行扫描的方式解决,阴极射线枪发出电子束打在涂有荧光粉的荧光屏上,产生GRB 基色,合成一个彩色像素。

扫描从屏幕的左上方开始,从左到右,从上到下,逐行扫描,每扫完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行行同步;扫描完所有行,用场同步信号进行场同步,并使扫描回到屏幕的左上方,同时进行场消隐,并预备进行下一次的扫描。

要实现VGA显示就要解决数据来源、数据存储、时序实现等问题,其中关键还是如何实现VGA时序。

VGA的标准参考显示时序如图1所示。

行时序和帧时序都需要产生同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序段(Display interval c)和显示前沿(Front porch d)四个部分。

2、方案设计由VGA的显示原理可知,该任务的关键是VGA时序控制部分和汉字图形显示部分:(1)VGA时序控制部分,采用FPGA本地50MHz时钟,根据所需时序要求,经Verilog语言编写的计数模块分频而得到,该部分十分重要,如果产生的时序有偏差,那么就会使汉字图形无法显示或显示结果混乱;(2)汉字图形显示部分,有2种方法可以实现:第1 种是在对像素进行行计数、场计数的时候,就把字库信息直接赋值给颜色信号R、G、B,这种方法虽然简单,但是控制很不灵活,需要对汉字的显示像素一一判定对应的位置,容易出现错误,不易修改,所以本次采用的是第2 种方法,第2 种方法是使用FPGA内部的一种资源来存储汉字的字库信息,然后由程序将其提取出来作为显示信号发送到VGA 接口,以实现汉字图形的显示,这样就克服了第一种方法易出错又不易修改的缺点。

在FPGA 中可以作为存储器件的资源主要有块RAM,本次任务就采用块RAM 来存储汉字图形的信息。

块RAM 是FPGA 内部的一种专用的资源,多数是分布在FPGA 边缘,因此叫做块RAM。

目前大多数的FPGA 都有内嵌的块RAM。

块RAM 是一种可同步配置的块,它的使用大大扩展了FPGA 的应用范围和灵活性。

FPGA 内嵌的块RAM 一般可以灵活的配置成单口RAM(single port RAM,SPRAM)、双口RAM (double port RAM,DPRAM)、内容寻址存储器(content addressable memory,CAM)以及先进先出存储器(first in first out,FIFO)等常用的存储结构。

3、VGA显示控制器“VGA显示控制器”接收时序控制信号、行列控制信号,根据显示内容需要产生相应的ROM 数据读取控制信号,发送给ROM地址发生器,用于产生相应的地址数据,并将收到的R、G、B分量的串行数据发送给对应的VGA引脚,用于汉字图形的显示,同时还可以控制显示图形的颜色(共8种)。

4、ROM地址发生器“ROM地址发生器”接收所要显示的数据读取控制信号,产生对应得ROM地址,根据VGA 显示的像素分布,确定读取对应数据的地址,由于所显示的图形每行需256个像素,而ROM 中每个地址存储的数据时64位,故每4个地址取出的数据用于一行的显示。

5、ROM存储器“ROM存储器”为FPGA内部块RAM配置成的单端口ROM,用于存储汉字图形的字模数据,根据ROM地址将相应的显示内容的数据传送给数据并串转换模块。

为了便于控制显示图形和容易编程,现制定显示区域为512行256列,每列为1bit,共为数据为512x256=131072bit,因此ROM的设定应该是:设定WORD为64bit ,则深度为:131072/64=2048=2^12,所以ROM的地址线为12根,建立的ROM与.mif文件。

6、数据并串转换模块因为从ROM中直接读出的数据是64bit的,而用于每一个像素显示的数据需要1bit的串行输出,因此需加入该模块进行将64位的显示数据转换成R、G、B三个分量各自对应的数据串行输出到VGA显示控制器,用于图像的实际显示。

实验程序如下:(此程序运行需要设置ROM,并要生成.mif文件)如有问题可联系QQ:472373532module VGA_DIS(clk,rst,hsync,vsync,r,g,b,ROM_DATA,ROM_ADDR);input clk; //50M时钟input rst; //复位信号output hsync;//行同步信号output vsync;//场同步信号output [10:0] ROM_ADDR;input[63:0] ROM_DATA;//三原色接口信号output r;output g;output b;reg[10:0] x;//行坐标reg[10:0] y;//列坐标always @(posedge clk or negedge rst)beginif(!rst)x<=10'd0;else if(x==11'd1056)x<=10'd0;elsex<=x+1'b1;endalways @(posedge clk or negedge rst)beginif(!rst)y<=10'd0;else if(y==11'd628)y<=10'd0;else if (x==11'd1056)y<=y+1'b1;endwire valid;assign valid = (x>11'd216)&&(x<11'd1016)&&(y>11'd27)&&(y<11'd627); wire [10:0]x_valid,y_valid;assign x_valid=x-11'd216;assign y_valid=y-11'd27;reg hsync_r,vsync_r;always@(posedge clk or negedge rst)if(!rst)beginhsync_r<=1'b0;vsync_r<=1'b0;endelsebeginhsync_r<=(x<=10'd160);vsync_r<=(y<=10'd5);endassign hsync=hsync_r;//行同步信号assign vsync=vsync_r;//场同步信号//--------------------------------------------------// VGA色彩信号产生reg[7:0] m;reg[3:0] X=4'd1 ;//这里X,Y定义了汉字显示的坐标reg[3:0] Y=4'd0;reg flag;//设置标志位用来使不显示汉字以外为通一背景色reg flag1;reg [3:0] temp;wire [3:0] temp1;always @(posedge clk or negedge rst)if(!rst)m<=8'd0;else if(valid&&(x_valid-256*X)<=256&&(x_valid-256*X)>=0)//列变量 beginflag<=1'b1;m<=x_valid[7:0];temp<=m/64;endelse// m<=6'd0;flag<=1'b0;reg[8:0] n;always @(posedge clk or negedge rst)if(!rst)n<=9'd0;else if(valid&&(y_valid-512*Y)<=512&&(y_valid-512*Y)>=0)//行变量beginn<=y_valid[8:0];flag1<=1'b1;endelse// n<=6'd0;flag1<=1'b0;assign temp1=m/64;assign ROM_ADDR=4*n+temp1;assign r=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0; assign g=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0; assign b=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0;//assign r=valid ?d_rec :1'b0;//assign g=valid ?~(u_rec |d_rec) : 1'b0;//assign b=valid ? u_rec : 1'b0;endmoduleQQ:472373532module VGA_DIS(clk,rst,hsync,vsync,r,g,b,ROM_DATA,ROM_ADDR); input clk; //50M时钟input rst; //复位信号output hsync;//行同步信号output vsync;//场同步信号output [10:0] ROM_ADDR;input[63:0] ROM_DATA;//三原色接口信号output r;output g;output b;reg[10:0] x;//行坐标reg[10:0] y;//列坐标always @(posedge clk or negedge rst)beginif(!rst)x<=10'd0;else if(x==11'd1056)x<=10'd0;elsex<=x+1'b1;endalways @(posedge clk or negedge rst)beginif(!rst)y<=10'd0;else if(y==11'd628)y<=10'd0;else if (x==11'd1056)y<=y+1'b1;endwire valid;assign valid = (x>11'd216)&&(x<11'd1016)&&(y>11'd27)&&(y<11'd627); wire [10:0]x_valid,y_valid;assign x_valid=x-11'd216;assign y_valid=y-11'd27;reg hsync_r,vsync_r;always@(posedge clk or negedge rst)if(!rst)beginhsync_r<=1'b0;vsync_r<=1'b0;endelsebeginhsync_r<=(x<=10'd160);vsync_r<=(y<=10'd5);endassign hsync=hsync_r;//行同步信号assign vsync=vsync_r;//场同步信号//--------------------------------------------------// VGA色彩信号产生reg[7:0] m;reg[3:0] X=4'd1 ;//这里X,Y定义了汉字显示的坐标reg[3:0] Y=4'd0;reg flag;//设置标志位用来使不显示汉字以外为通一背景色reg flag1;reg [3:0] temp;wire [3:0] temp1;always @(posedge clk or negedge rst)if(!rst)m<=8'd0;else if(valid&&(x_valid-256*X)<=256&&(x_valid-256*X)>=0)//列变量beginflag<=1'b1;m<=x_valid[7:0];temp<=m/64;endelse// m<=6'd0;flag<=1'b0;reg[8:0] n;always @(posedge clk or negedge rst)if(!rst)n<=9'd0;else if(valid&&(y_valid-512*Y)<=512&&(y_valid-512*Y)>=0)//行变量beginn<=y_valid[8:0];flag1<=1'b1;endelse// n<=6'd0;flag1<=1'b0;assign temp1=m/64;assign ROM_ADDR=4*n+temp1;assign r=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0; assign g=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0; assign b=valid ? ~ROM_DATA[6'd63-(m-64*temp1)]&&flag&&flag1 : 1'b0;//assign r=valid ?d_rec :1'b0;//assign g=valid ?~(u_rec |d_rec) : 1'b0;//assign b=valid ? u_rec : 1'b0;endmodule。

相关主题