FPGA实例02——vga接口

本文详细介绍了VGA信号中的行同步信号(hys)、场同步信号(vys)以及颜色三原色的工作原理,并以640*480分辨率为例,展示了hys的时序。通过计算得出基准时钟周期,并设计了一个包含行、列计数器的驱动模块,用于生成hys和vys信号。此外,还讨论了由于实际时钟频率与基准时钟不匹配,需要使用PLL IP核进行分频的问题。最后,给出了顶层模块如何调用PLL和驱动模块完成设计的示例。
摘要由CSDN通过智能技术生成

1.vga我们要用时用的较多的信号是行同步信号hys、场同步信号vys、颜色三原色红R、绿G、蓝B

2.如图,以640*480的分辨率为例,hys的时序如图所示,而vys与hys类似,不同的只是数据和单位。
在这里插入图片描述
hys的单位是基准时钟,而vys的单位是行,见下表:
在这里插入图片描述

3.场同步信号和行同步信号均处于显示区域的时候,才是真正的显示区域

4.基准时钟的计算:与分辨率的刷新率有关
若为60HZ,意味着一秒显示60幅图像,而一幅图像占据800x525个时钟,所以基准时钟周期 = (1/60)/(800x525),约为39.68ns,时钟晶振约为25M。

5.先设计一个驱动模块:

	module color
	(
	    clk,
	    rst_n,
	    hys,
	    vys,
	    lcd_rgb
	);											//5个接口:时钟、复位、行、列、rgb显示
	
	
	
	input           clk;
	input           rst_n;
	output          hys;
	output          vys;
	output [15:0]   lcd_rgb;				   //输入输出声明
	
	
	
	reg [9:0]       h_cnt;                      //行信号计数器,最大为800个基准时钟
	wire            add_h_cnt;
	wire            end_h_cnt;
	
	
	reg [9:0]       v_cnt;                      //列信号计数器,最大为525个基准时钟
	wire            add_v_cnt;
	wire            end_v_cnt;
	
	
	reg             hys;
	reg             vys;
	reg             red_area;
	reg [15:0]      lcd_rgb;					//16位的rgb信号
	
	
	always @(posedge clk or negedge rst_n)begin
	    if(!rst_n)begin
	        h_cnt <= 0;
	    end
	    else if(add_h_cnt)begin
	        if(end_h_cnt)
	            h_cnt <= 0;
	        else
	            h_cnt <= h_cnt + 1;
	    end
	end
	
	assign add_h_cnt =1 ;       
	assign end_h_cnt = add_h_cnt && h_cnt==800-1 ;   	//计数器0:行基准时钟计数
	

	always  @(posedge clk or negedge rst_n)begin
	    if(rst_n==1'b0)begin
	        hys <= 0;
	    end
	    else if(add_h_cnt && h_cnt==96-1)begin			//由时序图可知,在96个基准时钟后将hys拉高
	        hys <= 1;
	    end
	    else if(end_h_cnt)begin
	        hys <= 0;
	    end
	end

	
	always @(posedge clk or negedge rst_n)begin
	    if(!rst_n)begin
	        v_cnt <= 0;
	    end
	    else if(add_v_cnt)begin
	        if(end_v_cnt)
	            v_cnt <= 0;
	        else
	            v_cnt <= v_cnt + 1;
	    end
	end
	
	assign add_v_cnt =end_h_cnt ;       
	assign end_v_cnt = add_v_cnt && v_cnt==525-1 ;      	//计数器1:列计数
	
	
	always  @(posedge clk or negedge rst_n)begin
	    if(rst_n==1'b0)begin
	        vys <=0;
	    end
	    else if(add_v_cnt && v_cnt==2-1)begin					//在第二列时将vys信号拉高
	        vys <=1;
	    end
	    else if(end_v_cnt)begin
	        vys <=0;
	    end
	end

	
	always  @(*)begin
	    red_area = (h_cnt >= (96+48) && h_cnt<(96+48+640)) && (v_cnt>=(2+33) && v_cnt<(2+33+480));
	end						//显示的有效区域
	

	always  @(posedge clk or negedge rst_n)begin
	    if(rst_n==1'b0)begin
	        lcd_rgb <= 0;
	    end
	    else if(red_area)begin
	        lcd_rgb <= 16'b11111_000000_00000;  //显示功能
	    end
	    else begin
	        lcd_rgb <= 0;
	    end
	end
	

	endmodule

5.因为基准时钟为25M,而我们的时钟是50M,因此需要引用PLL的IP核来对时钟进行分频。

6.分频后,在顶层模块调用pll和驱动模块即可完成设计。

	module color_top
	(
	    clk,
	    rst_n,
	    hys,
	    vys,
	    lcd_rgb
	);
	
	input           clk;
	input           rst_n;
	output          hys;
	output          vys;
	output [15:0]   lcd_rgb;
	
	
	wire            clk_0;
	wire            hys;
	wire            vys;
	wire [15:0]     lcd_rgb;
	
	
	my_pll module_1     //调用PLL  ip核
	(
		.inclk0 (clk),
		.c0     (clk_0)
	);
	
	
	color module_2		//调用驱动模块
	(
	    .clk(clk_0),
	    .rst_n(rst_n),
	    .hys(hys),
	    .vys(vys),
	    .lcd_rgb(lcd_rgb)
	);
	
	endmodule

最后的RTL电路如图所示:
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值