EDN首页   博客首页

日志档案

发表于 2008-8-6 19:14:39

2

标签: verilog  VGA  接口驱动  

基于verilog的VGA简单接口驱动

基于verilogVGA简单接口驱动

 

       断断续续的利用业余的时间终于搞定了VGA的驱动,从VGA的显像原理到接口的定义再到编程驱动。其实现在想想还是蛮简单的,显像的原理就不废话了,前面的日志里有详细的说明,今天就主要谈一下用verilogVGA编程驱动。

       FPGA芯片用的还是Spartan3系列的xc3s400。即使是编程,也还是不得不先看看它的接口连接电路:

点击看大图

       标准VGA一共15个接口(拔下你家的液晶或是CRT显示器看看就知道了),真正用到的信号接口不多,就五个,HSYNC是行同步信号,VSYNC是场同步信号,VGA_RVGA_GVGA_B是三原色信号,这三个信号接口都是输入模拟信号的,所以它们都有相应的地线需要连接。我的这块FPGA开发板上面做的比较简单,直接用IO口去连接VGA的五个信号接口了,并且三原色信号接口输入的只可能是数字信号(01),因此驱动液晶屏上显示的颜色最多也就8种,一般来说,可以在FPGAVGA接口间加一个DA模块的设计,这样就可能实现65536或者更多种可能的配色效果。

       看完接口电路,就看程序吧,这个程序要实现的显示效果很简单,屏幕是800*60015寸液晶)的,如图:

点击看大图 

Verilog代码以及详细注释如下:

module vga_rgb8(clk,rst_n,hsync,vsync,vga_r,vga_g,vga_b);

 

input clk;       //50MHz

input rst_n;    //低电平复位

output hsync; //行同步信号

output vsync; //场同步信号

       //三原色信号接口RGB

output vga_r;

output vga_g;

output vga_b;

 

//--------------------------------------------------

reg[9:0] x_cnt;      //行坐标(这里包括了行同步、后沿、有效数据区、前沿)

reg[9:0] y_cnt;      //列坐标(这里包括了场同步、后沿、有效数据区、前沿)

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) x_cnt <= 10'd0;

       else if(x_cnt == 10'd1000) x_cnt <= 10'd0;           //行计数只记到1000

       else x_cnt <= x_cnt+1'b1;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) y_cnt <= 10'd0;

       else if(y_cnt == 10'd665) y_cnt <= 10'd0;             //场同步只记到665

       else if(x_cnt == 10'd1000) y_cnt <= y_cnt+1'b1;//每计数完一行,场同步就加一

 

//--------------------------------------------------

wire valid;      //有效数据显示区标志,就是你在液晶屏幕上可以看到的区域

/*要说明的一点是,当坐标不处于有效显示区时,RGB三原色信号接的电平都必须拉底(0*/

 

assign valid = (x_cnt > 10'd180) && (x_cnt < 10'd980)

                                   && (y_cnt > 10'd35) && (y_cnt < 10'd635);

 

wire[9:0] xpos,ypos;    //有效显示区坐标

 

assign xpos = x_cnt-10'd180;

assign ypos = y_cnt-10'd35;

 

//--------------------------------------------------

reg hsync_r,vsync_r;

 

always @ (posedge clk or negedge rst_n)

   if (!rst_n) begin

              hsync_r <= 1'b0;

      vsync_r <= 1'b0;

      end

   else begin

      hsync_r <= x_cnt <= 10'd50;  //产生hsync信号(行同步)

      vsync_r <= y_cnt <= 10'd6;   //产生vsync信号(场同步)

      end

 

assign hsync = hsync_r;

assign vsync = vsync_r;

 

//--------------------------------------------------

       //显示一个矩形框

wire a_dis,b_dis,c_dis,d_dis;     //矩形框显示区域定位

 

assign a_dis = ( (xpos>=200) && (xpos<=220) )

                            && ( (ypos>=140) && (ypos<=460) );

                           

assign b_dis = ( (xpos>=580) && (xpos<=600) )

                            && ( (ypos>=140) && (ypos<=460) );

 

assign c_dis = ( (xpos>=220) && (xpos<=580) )

                            && ( (ypos>140)  && (ypos<=160) );

                           

assign d_dis = ( (xpos>=220) && (xpos<=580) )

                            && ( (ypos>=440) && (ypos<=460) );

 

       //显示一个小矩形

wire e_rdy;    //矩形的显示有效矩形区域

 

assign e_rdy = ( (xpos>=385) && (xpos<=415) )

                            && ( (ypos>=285) && (ypos<=315) );

 

//--------------------------------------------------

       //r,g,b控制液晶屏颜色显示,背景显示蓝色,矩形框显示红蓝色

assign vga_r = valid ? e_rdy : 1'b0;

assign vga_g = valid ?  (a_dis | b_dis | c_dis | d_dis) : 1'b0;

assign vga_b = valid ? ~(a_dis | b_dis | c_dis | d_dis) : 1'b0;  

 

endmodule

 

 

系统分类: CPLD/FPGA   |   用户分类: FPGA/CPLD   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(857)    回复(3)  

投一票您将和博主都有获奖机会!

最新评论

  • cqcrr

    2008-8-8 10:30:34

    不错,但是也不能说真正用到的信号接口不多,就五个,多一些接地的接口是很重要的。

  • ren

    2008-8-18 11:15:40

    hsync_r <= x_cnt <= 10'd50; //产生hsync信号(行同步) vsync_r <= y_cnt <= 10'd6; //产生vsync信号(场同步) 请问这两代码是什么意思,能给解释一下吗?

  • ilove314

    2008-8-19 21:34:16

    hsync_r <= x_cnt <= 10'd50; //当x_cnt <= 10'd50时,hsync_r <= 1'b1;否则hsync_r <= 1'b0 后面一个类似