本博文介绍下spartan-3e start kit board上的VGA接口的用法。
一、VGA简介
VGA(Video Graphics Array)是IBM于1987年提出的一个使用模拟信号的电脑显示标准,最早指的是显示器
640X480这种显示模式。本实验程序用的是640X480模式,即每一行有640个像素,整个显示区域一共有480
行。VGA接口是一种D型接口,采用非对称分布的15pin 连接方式,共有15针,分成3排,每排5个孔。本实验条
件下只使用其中5个pin,分别是红色信号输入(R)、绿色信号输入(G)、蓝色信号输入(B),行同步信号输入(h_sync)
和场同步信号输入(v_sync)。
二、VGA时序
VGA的扫描顺序是从左到右,从上到下。例如在640X480的显示模式下,从显示器的左上角开始往右扫描,直到
640个像素扫完,再回到最左边,开始第二行的扫描,如此往复,到第480行扫完时即完成一帧图像的显示。这时
又回到左上角,开始下一帧图像的扫描。如果每秒能完成60帧,则称屏幕刷新频率为60Hz。宏观上,一帧屏幕由
480个行和640个列填充而成,而实际上,一帧屏幕除了显示区,还包含其他未显示部分,作为边框或者用来同步。
具体而言,一个完整的行同步信号包含了左边框、显示区、右边框还有返回区四个部分,总共800个像素,其分配
如下:
左边框:48个
显示区:640个
右边框:16个
返回区:96个
同样的,一个完整的垂直同步信号也分为四个区域,总共525个像素,分配如下:
顶边框:33个
显示区:480个
底边框:10个
返回区:2个
三、VGA在各种像素及刷新频率下的各段长度对照表
四、VGA显示颜色编码表
五、实验设计
1、K17作为复位键,按下后各种信号均清零,屏幕显示黑色。
2、滑动开关SW0(L13)、SW1(L14)作为输入,当SW1 SW0=00,屏幕竖向显示8种颜色;当SW1 SW0=01,屏幕
横向显示8种颜色;当SW1 SW0=1X,屏幕只显示一种颜色。
六、实验结果
六、不得不说的一些问题
1、用VGA连接线将板子上的接口与笔记本的接口连起来,一点反应都没有?!
因为笔记本上的VGA接口是输出口,不能输入!也基本就是说要把VGA连接线接到台式机的显示屏才可以做出
结果来。
2、VGA频率的计算?
就是相应像素x刷新频率了。就本实验来说就是800*525*60=25200000HZ了。所以在verilog源码中可以看到已
经对板子的频率(50MHZ)二分频(25MHZ)了。
3、从上面的VGA时序图中可以发现行、场同步信号都是低电平有效。行场同步期间以及显示前沿、显示后沿
其中,输出RGB信号都是无效的,此时RGB=3'b000,否则无法正常显示。
4、扫描是从上到下、从左到右依次进行的。每次电子束其实只是扫描到一个像素点罢了,由于扫描速度很快,
我们感觉是全部扫描的。
5、代码中必须确定每一个像素点的RGB信号值。这也就是说代码中必须有对行列的计数值。行为800个像素,
行同步96+显示后沿48=144个像素是不用显示的。此后显示640个像素。再然后显示前沿16个像素也不显示。
列的显示同理可推。
七、代码
1、verilog源码
module VGA( CLK, RST, DIN, DOUT,VGA_HSYNC, VGA_VSYNC ); input CLK; // System clock= 50MHz input RST; // high active input [1:0] DIN; output [2:0] DOUT;// RGB output VGA_HSYNC; output VGA_VSYNC; reg [2:0] RGB; reg [9:0] h_cnt;//horizontal counter reg [9:0] v_cnt; // vertical counter reg VGA_CLK; // VGA clock = 25MHz wire [1:0] state; wire data_valid; assign DOUT = data_valid ? RGB:3'd0; //数据无效时,RGB必须为全0 assign state = DIN; assign VGA_HSYNC = ( h_cnt >= 10'd96 )? 1'b1 : 1'b0; assign VGA_VSYNC = ( v_cnt >= 10'd2 )? 1'b1 : 1'b0; assign data_valid = ((h_cnt > 10'd143) && (h_cnt < 10'd784) && (v_cnt > 10'd34) && (v_cnt < 10'd515)); /////// Generate VGA CLOCK = 25MHz /////// always @ (posedge CLK or posedge RST)begin if(RST) VGA_CLK <= 1'b0; else VGA_CLK <= ~VGA_CLK; end /////// horizontal counter /////// always @(posedge VGA_CLK or posedge RST)begin if(RST) h_cnt <= 10'd0; else if (h_cnt == 10'd799) h_cnt <= 10'd0; else h_cnt <= h_cnt + 1'b1; end /////// vertical counter /////// always @(posedge VGA_CLK or posedge RST)begin if(RST) v_cnt <= 10'd0; else if (v_cnt == 10'd524) v_cnt <= 10'd0; else if(h_cnt == 10'd799) v_cnt <= v_cnt + 1'b1; else v_cnt <= v_cnt; end always @ (posedge CLK or posedge RST) begin if(RST) begin RGB <= 3'd0; end else begin case (state) 2'b00: begin if ((h_cnt > 10'd143) && (h_cnt <= 10'd223)) RGB <= 3'd000; else if ((h_cnt > 10'd223) && (h_cnt <= 10'd303)) RGB <= 3'b001; else if ((h_cnt > 10'd303) && (h_cnt <= 10'd383)) RGB <= 3'b010; else if ((h_cnt > 10'd383) && (h_cnt <= 10'd463)) RGB <= 3'b011; else if ((h_cnt > 10'd463) && (h_cnt <= 10'd543)) RGB <= 3'b100; else if ((h_cnt > 10'd543) && (h_cnt <= 10'd623)) RGB <= 3'b101; else if ((h_cnt > 10'd623) && (h_cnt <= 10'd703)) RGB <= 3'b110; else if ((h_cnt > 10'd703) && (h_cnt <= 10'd783)) RGB <= 3'b111; end 2'b01: begin if ((v_cnt > 10'd34) && (v_cnt <= 10'd94)) RGB <= 3'd000; else if ((v_cnt > 10'd94) && (v_cnt <= 10'd154)) RGB <= 3'b001; else if ((v_cnt > 10'd154) && (v_cnt <= 10'd214)) RGB <= 3'b010; else if ((v_cnt > 10'd214) && (v_cnt <= 10'd274)) RGB <= 3'b011; else if ((v_cnt > 10'd274) && (v_cnt <= 10'd334)) RGB <= 3'b100; else if ((v_cnt > 10'd334) && (v_cnt <= 10'd394)) RGB <= 3'b101; else if ((v_cnt > 10'd394) && (v_cnt <= 10'd454)) RGB <= 3'b110; else if ((v_cnt > 10'd454) && (v_cnt <= 10'd514)) RGB <= 3'b111; end default: RGB <= 3'b101; endcase end end endmodule
2、ucf约束文件
NET "CLK" LOC = "C9" | IOSTANDARD = LVCMOS33 ; NET "CLK" PERIOD = 20.0ns HIGH 40%; NET "RST" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ; NET "DOUT[2]" LOC = "H14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; NET "DOUT[1]" LOC = "H15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; NET "DOUT[0]" LOC = "G15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; NET "VGA_VSYNC" LOC = "F14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; NET "VGA_HSYNC" LOC = "F15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; NET "DIN[0]" LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ; NET "DIN[1]" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ;