【FPGA开发】VGA彩条显示及VGA白块位移

这篇具有很好参考价值的文章主要介绍了【FPGA开发】VGA彩条显示及VGA白块位移。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 实验目的:

为了理解VGA的工作模式,并且进行vga一部分的模板开发,方便后续图像处理显示的需求。这里通过对vga时序进行分析,进行简单的vga图像控制。实验阶段进行的是640*480@60hz的分辨率和刷新率,后续因为需要适应显示器的规格。会在模块化的阶段进行参数的重新分配,变成可编辑参数模块。

2. 实验步骤

2.1 实现vga的彩条显示

2.2 实现vga的白块位移

2.3 实现vga的模块化处理(后续进行)

3. 实验原理:

3.1 VGA接口介绍:

我们的开发板上VGA输出的是8bits,这是因为我们选用了256色的VGA接口,并且使用了一个DAC芯片,对FPGA输出的数字信号进行数模转换。

【FPGA开发】VGA彩条显示及VGA白块位移,fpga开发


VGA输出的是模拟信号,因此在比较高的分辨率的时候,往往会出出现边缘模糊,失真的情况,在这些情况下,我们就会使用hdmi等等数字信号的接口。一般情况下VGA输出的最高分辨为1080p.

3.2 VGA显像介绍:

 VGA显示图像使用扫描的方式,从第一行的第一个像素开始,逐渐填充,第一行第一个、第一行第二个,第二行第一个、第二行第二,第n行最后一个。

通过这种方式构成一帧完整的图像,当扫描速度足够快,加之人眼的视觉暂留特性,我们会看到一幅完整的图片,而不是一个个闪烁的像素点。这就是VGA 显示的原理。

VGA有两个非常重要的信号,一个是行同步信号(HSYNC),另一个是场同步信号(VSYNC)。通过这两个信号完成一帧图像的像素点扫描

也就是当HSYNC,VSYNC的高电平来临,VGA显示器就知道,我要开始接收这一行或列要显示的像素信息的,当下一个高电平来临时,那么这一行的图像信息就传输完成了,其中真正要显示的图像信息就蕴含在这一周期中。

具体参数如下: 

我们可以看到,我们要显示一个图像的时候,还会包含后沿,前沿这些部分。这些都是要考虑到我们的计数器中去的。

-这里我们要使用的是640*480@60 具体参数如下表格所示

【FPGA开发】VGA彩条显示及VGA白块位移,fpga开发

下面我们就开始具体代码的编写。具体对参数的一些图像绘制如下

【FPGA开发】VGA彩条显示及VGA白块位移,fpga开发

4. 代码实现:

4.1 vga_ctrl:

这段代码实现的是vga在显示器上三个彩条的显示,之前忘了保存显示的照片,这里就只展示我们代码部分。


// -----------------------------------------------------------------------------
// Copyright (c) 2014-2024 All rights reserved
// -----------------------------------------------------------------------------
// Author : XIBO WU (Gatsby) wuxibo2023@163.com
// File   : vga_ctrl.v
// Create : 2024-01-15 09:48:57
// Revise : 2024-01-17 11:30:20
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------

module vga_ctrl(
		input wire 			i_vclk,
		input wire 			i_rst,

		output wire 		o_hsync,    //水平也就是行
		output wire 		o_vsync,	//垂直也就是列
		output wire [7:0]	o_rgb
	);

	//output logic 
	reg 		hsync;
	reg			vsync;
	reg [7:0]	rgb;

	assign o_hsync = hsync;
	assign o_vsync = vsync;
	assign o_rgb   = rgb;

	reg	[11:0]	h_cnt;	//列
	reg	[11:0]	cnt_v;	//行


	//hv cnt
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			h_cnt <= 'd0;
		end
		else if (h_cnt == 'd799) begin
			h_cnt <= 'd0;
		end
		else begin
			h_cnt <= h_cnt + 'd1;
		end
	end


	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			cnt_v <= 'd0;
		end
		else if (cnt_v == 'd524 && h_cnt == 'd799) begin
			cnt_v <= 'd0;
		end
		else if(h_cnt == 'd799)begin
			cnt_v <= cnt_v + 'd1;
		end
		else begin
			cnt_v <= cnt_v;
		end
	end

	//sync
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			vsync <= 1'b0;
		end
		else if(h_cnt == 'd799) begin
			vsync <= 1'b1;
		end
		else if(h_cnt == 'd95)begin
			vsync <= 1'b0;
		end
		else begin
			vsync <= vsync;
		end
	end

	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			hsync <= 1'b0;
		end
		else if (cnt_v == 'd524 && h_cnt == 'd799) begin
			hsync <= 1'b1;
		end
		else if (cnt_v == 'd1 && h_cnt == 'd799)begin
			hsync <= 1'b0;
		end
		else begin
			hsync <= hsync;
		end
	end


	//rgb
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			rgb <= 8'b000_000_00;
		end
		else if (cnt_v >= 'd35 && cnt_v <= 'd194 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b111_000_00;
		end
		else if (cnt_v >= 'd195 && cnt_v <= 'd354 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b000_111_00;
		end
		else if (cnt_v >= 'd355 && cnt_v <= 'd514 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b000_000_11;
		end
		else begin
			rgb <= 8'b000_000_00; 
		end
	end

endmodule

4.2 vga_shift:

这段代码显示的是在彩条的基础上增加了白框的移动,按照我们的分辨率来说,我们的刷新频率是60hz,因此我们每一帧都对白框进行一个像素点的位移,等到碰到边框的时候再朝反方向位移。最后实现一个类似于屏幕保护界面的效果。这里也一样仅展示代码


// -----------------------------------------------------------------------------
// Copyright (c) 2014-2024 All rights reserved
// -----------------------------------------------------------------------------
// Author : XIBO WU (Gatsby) wuxibo2023@163.com
// File   : vga_shift.v
// Create : 2024-01-16 13:25:01
// Revise : 2024-01-17 11:37:03
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
 module vga_shift(
 		input wire 				i_vclk,
 		input wire				i_rst,

 		output wire 			o_hsync,
 		output wire 			o_vsync,
 		output wire [7:0] 		o_rgb
 	);

	//output logic 
	reg 		hsync;
	reg			vsync;
	reg [7:0]	rgb;

	assign o_hsync = hsync;
	assign o_vsync = vsync;
	assign o_rgb   = rgb;

	reg	[11:0]	h_cnt;	//列
	reg	[11:0]	v_cnt;	//行

	reg			x_dir;	 //x轴的行进方向	 0向右 1向左
	reg			y_dir;   //y轴的行进反向  0向下 1向上
	reg	[9:0]	x_pixel; //x轴坐标像素
	reg	[9:0]	y_pixel; //y轴坐标像素


	//x direction
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			x_dir <= 1'b0;
		end
		else if (x_pixel == 'd439 && v_cnt == 'd524 && h_cnt == 'd799) begin
			x_dir <= 1'b1;
		end
		else if (x_pixel == 'd0 && v_cnt == 'd524 && h_cnt == 'd799) begin
			x_dir <= 1'b0;
		end
		else begin
			x_dir <= x_dir;
		end
	end


	//y direction
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			y_dir <= 1'b0;
		end
		else if (x_pixel == 'd279 && v_cnt == 'd524 && h_cnt == 'd799) begin
			y_dir <= 1'b1;
		end
		else if (x_pixel == 'd0 && v_cnt == 'd524 && h_cnt == 'd799) begin
			y_dir <= 1'b0;
		end
		else begin
			y_dir <= x_dir;
		end
	end


	//x_pixel
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			x_pixel <= 'd0;
		end
		else if (x_dir == 1'b0 && v_cnt == 'd524 && h_cnt == 'd799) begin
			x_pixel <= x_pixel + 'd1;
		end
		else if (x_dir == 1'b1 && v_cnt == 'd524 && h_cnt == 'd799) begin
			x_pixel <= x_pixel - 'd1;
		end
		else begin
			x_pixel <= x_pixel;
		end
	end

	//y_pixel
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			y_pixel <= 'd0;
		end
		else if (y_dir == 1'b0 && v_cnt == 'd524 && h_cnt == 'd799) begin
			y_pixel <= y_pixel + 'd1;
		end
		else if (y_dir == 1'b1 && v_cnt == 'd524 && h_cnt == 'd799) begin
			y_pixel <= y_pixel - 'd1;
		end
		else begin
			y_pixel <= y_pixel;
		end
	end


	//hv cnt
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			h_cnt <= 'd0;
		end
		else if (h_cnt == 'd799) begin
			h_cnt <= 'd0;
		end
		else begin
			h_cnt <= h_cnt + 'd1;
		end
	end


	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			v_cnt <= 'd0;
		end
		else if (v_cnt == 'd524 && h_cnt == 'd799) begin
			v_cnt <= 'd0;
		end
		else if(h_cnt == 'd799)begin
			v_cnt <= v_cnt + 'd1;
		end
		else begin
			v_cnt <= v_cnt;
		end
	end

	//sync
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			vsync <= 1'b0;
		end
		else if(h_cnt == 'd799) begin
			vsync <= 1'b1;
		end
		else if(h_cnt == 'd95)begin
			vsync <= 1'b0;
		end
		else begin
			vsync <= vsync;
		end
	end

	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			hsync <= 1'b0;
		end
		else if (v_cnt == 'd524 && h_cnt == 'd799) begin
			hsync <= 1'b1;
		end
		else if (v_cnt == 'd1 && h_cnt == 'd799)begin
			hsync <= 1'b0;
		end
		else begin
			hsync <= hsync;
		end
	end


	//rgb
	always @(posedge i_vclk) begin
		if (i_rst == 1'b1) begin
			rgb <= 8'b000_000_00;
		end
		else if(v_cnt >= ('d35 + y_pixel) && v_cnt <= ('d234 + y_pixel) && h_cnt >= ('d144 + x_pixel) && v_cnt <= ('d343 + x_pixel)) begin
			rgb <= 8'b111_111_11;
		end
		else if (v_cnt >= 'd35 && v_cnt <= 'd194 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b111_000_00;
		end
		else if (v_cnt >= 'd195 && v_cnt <= 'd354 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b000_111_00;
		end
		else if (v_cnt >= 'd355 && v_cnt <= 'd514 && h_cnt >= 'd144 && h_cnt <= 'd783) begin
			rgb <= 8'b000_000_11;
		end
		else begin
			rgb <= 8'b000_000_00; 
		end
	end






 endmodule

4.3 top_vga:

需要注意的是,我们的刷新率为60hz每帧我们需要传输640*480个像素的数据,算上我们的边界和同步也就是说,我们一张图片需要在1/60s内完成800*525个周期 = 25200000cycle/s 换算成时钟频率也就是25.2mhz,因此我们要完成图像60hz的显示我们至少需要25.2mhz的时钟,如果不能达到这个时钟频率的话,我们的刷新率就会达不到标准。所以在顶层,我们需要使用一个PLL来分频一个25mhz的时钟。我们板子上的晶振产生的时钟是50mhz,所有我们需要进行一次分频。

下面展示代码:


// -----------------------------------------------------------------------------
// Copyright (c) 2014-2024 All rights reserved
// -----------------------------------------------------------------------------
// Author : XIBO WU (Gatsby) wuxibo2023@163.com
// File   : top_vga.v
// Create : 2024-01-15 13:54:16
// Revise : 2024-01-16 16:28:11
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------

module top_vga(
		input wire 			i_sclk,
		input wire 			i_rst_n,

		output wire 		o_hsync,
		output wire 		o_vsync,
		output wire [7:0]	o_rgb	
	);

		
	
		//module instance
		wire 	   clk_25mhz;
		wire 	   clk_50mhz;
		wire       hsync;
		wire 	   vsync;
		wire [7:0] rgb;
		wire 	   rst;
		assign rst = ~i_rst_n;


	//PLL
	clk_gen_inst inst_clk(
    	// Clock out ports
    	.clk_50mhz(clk_50mhz),     // output clk_50mhz
    	.clk_25mhz(clk_25mhz),     // output clk_25mhz
	   // Clock in ports
    	.clk_in1(i_sclk)     	   // input clk_in1
    );




	//vga instance
	vga_ctrl inst_vga_ctrl(
		.i_vclk  (clk_25mhz),
		.i_rst   (rst),
		.o_hsync (hsync),
		.o_vsync (vsync),
		.o_rgb   (rgb)
	);

	vga_shift inst_vga_shift(
		.i_vclk  (clk_25mhz),
		.i_rst   (rst),
		.o_hsync (hsync),
		.o_vsync (vsync),
		.o_rgb   (rgb)
	);


		


endmodule

5. 实验总结:

在这个实验中,使用的是256色的vga,代码虽然实现了目的,但是缺点也很大,缺点在于只能实现对应分辨率和刷新率的功能,因此后面要有模块化开发的思维,方便后期的维护。或者说留下相应的接口,可以方便后续上位机可以直接更改分辨率和RGB内容。VGA是一个比较低速的一个视频接口,后续的文章中要实现hdmi的接口模拟,来实现比较高的分辨率和刷新率,来捕捉摄像头的一些实时画面。文章来源地址https://www.toymoban.com/news/detail-810949.html

到了这里,关于【FPGA开发】VGA彩条显示及VGA白块位移的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • fpga中Spartan6系列开发板和VGA显示实现贪吃蛇游戏设计

    鱼弦:CSDN内容合伙人、CSDN新星导师、全栈领域创作新星创作者 、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen) 需要用ise 14.7,板卡为spantan6系列,VGA显示实现贪吃蛇游戏的设计 ,需要一整套工程文件。 1.实现贪吃蛇游

    2024年02月03日
    浏览(47)
  • FPGA实现LCD显示屏显示彩条

    目录 总体设计  读显示屏ID  读显示屏ID代码 时钟分频  时钟分频代码  LCD显示 lcd显示模块 LCD驱动模块 lcd驱动代码 顶层模块 顶层模块代码 系统总体分为五个模块,分别是:rd_id(读显示屏ID模块),clk_div(时钟分频模块),lcd_display(lcd屏显示模块),lcd_driver(lcd屏驱动模块),和顶

    2024年02月16日
    浏览(29)
  • 记一次基于FPGA的VGA显示四操作数计算器工程的开发流程——(1)从顶层设计说起

    首先值得说明的是,在这个项目几乎完成之际,笔者才愈发体会到了硬件思维和软件思维的云泥之别。不幸的是,在此项目的实现过程中,绝大部分代码的思维仍然是软件思维,因此该项目主要模块的设计部分可能并不能体现硬件操作的独到之处,不符合硬件工程师的基本设

    2024年02月04日
    浏览(30)
  • (七)零基础FPGA图像处理——HDMI彩条显示实验

    此篇为专栏 《FPGA学习笔记》 的第七篇,记录我的学习FPGA的一些开发过程和心得感悟,刚接触FPGA的朋友们可以先去此专栏置顶 《FPGA零基础入门学习路线》来做最基础的扫盲。 本篇内容基于笔者实际开发过程和正点原子资料撰写,将会详细讲解此FPGA实验的全流程, 诚挚 地

    2024年02月03日
    浏览(45)
  • FPGA学习——VGA显示

    VGA(Video Graphics Array)是IBM在1987年随PS/2机⼀起推出的⼀种视频,具有分辨率⾼、显⽰速率快、颜⾊丰富等优点,在彩 ⾊显⽰器领域得到了⼴泛的应⽤。不⽀持热插拔,不⽀持⾳频传输。对于⼀些嵌⼊式VGA显⽰系统,可以在不使⽤VGA显⽰卡和计算机的 情况下,实现VGA图像的显⽰

    2024年02月04日
    浏览(29)
  • 基于FPGA的VGA图像显示

    引言:本文我们介绍利用FPGA实现VGA图像显示,主要介绍VGA硬件接口、VGA接口时序原理以及FPGA代码实现VGA接口时序、仿真等内容。 VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口

    2024年02月06日
    浏览(26)
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注:大部分参考内容来自“征途Pro《FPGA Verilog开发实战指南——基于Altera EP4CE10》2021.7.10(上)”  贴个下载地址: 野火FPGA-Altera-EP4CE10征途开发板_核心板 — 野火产品资料下载中心 文档 hdmi显示器驱动设计与验证 — [野火]FPGA Verilog开发实战指南——基于Altera EP4CE10 征途Pro开

    2024年02月09日
    浏览(37)
  • 【正点原子FPGA连载】第十六章DP彩条显示实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html DP接口即DisplayPort接口,DisplayPort是由视频电子标准协会(VESA)发布的显示接口。作为DVI的继任者,DisplayPort将在

    2024年02月11日
    浏览(32)
  • FPGA_简单工程_VGA显示驱动器

    一 理论 使用640*480@60显示模式,将数字信号转换位模拟信号,经由VGA进行显示。 使用3GM723,3路高清视频编码芯片。 3GM7123编码芯片:                                该芯片的主要功能是将RGB888的颜色数据转换成模拟的电压信号,然后进入到VGA接口的3个RGB接口。例如RGB8

    2024年02月20日
    浏览(30)
  • FPGA_工程_基于Rom的VGA图像显示

    一 工程框图 框图中,CLK_in,Vga_ctrl,Vga_pic模块已有,只需要对顶层模块进行修改,并将rom ip例化添加到Vga_pic模块的.v文件中,对Vga_pic的.v文件进行一定修改。 二 理论补充 显示图像的方法:                           使用matlab将图像格式转化为,.mif数据文件,再使用.m

    2024年02月20日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包