VGA接口驱动设计验证

news2024/11/15 4:33:05

前言

        VGA接口是一个很有历史的接口,全称为Video Graphics Array(VGA)视频图形阵列,是IBM公司在1987年随着PS/2一起推出的使用模拟信号的一种视频传输标准。时至今日,这个接口依然还在大量使用,因为这个接口具有成本低、结构简单、应用灵活的优点。VGA接口是一种广泛应用于计算机显示系统的标准模拟视频接口

正文

一、VGA接口驱动设计验证

        1.项目需求

        进行vga接口驱动设计验证(软件测试),使得图像数据通过VGA接口在显示器上显示一种颜色。

        2.技术介绍

        首先我们看一下 VGA 接口的电路原理图

VGA_VS是场脉冲信号,VGA_HS是行脉冲信号,VGA_R/G/B对应颜色数据。FPGA芯片直接与 VGA 接口相连,并没有特殊的外部芯片,也就是说,唯一要关注的可能就是它的显示原理和时序了。那么接下来我们具体来看一下 VGA 的扫描原理是什么。

        VGA 扫描方式 显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一 点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起 始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同 步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏 幕左上方,同时进行场消隐,开始下一帧。隔行扫描是指电子束扫描时每隔一行 扫一线,扫完一屏后再返回来扫描剩下的线,隔行扫描的显示器闪烁快速,可能 会使使用者眼睛疲劳(本实验采用逐行扫描的方式)

        扫描原理清楚以后,紧接着大家再来看看 VGA 的行、列同步时序

列同步时序

行同步时序

        VGA 中定义行时序和列时序都需要同步脉冲(a 段),显示后沿(b 段)、显 示时序段(c 段)和显示前沿(d 段)四部分。VGA 工业标准显示模式要求:行 同步、列同步都为负极性,即同步脉冲要求是负脉冲。

        由 VGA 行时序可知:每一行都有一个负极性行同步脉冲(a 段),是数据行 的结束标志,同时也是下一行的开始标志。在同步脉冲之后为显示后沿(b 段), 在显示时序段(c 段)显示器为亮的过程,RGB 数据驱动一行上的每一个像素点, 从而显示一行。在一行的最后为显示前沿(d 段)。在显示时间段之外没有图像 投射到屏幕,而是插入消隐信号。同步脉冲、显示后沿和显示前沿都是在行消隐 间隔内,当消隐有效时,RGB 信号无效,屏幕不显示数据。

        以本实验的显示标准 800*600*60Hz 为例。(800 为列数,600 为行数, 60Hz 为刷新一屏的频率)

        行时序:屏幕对应的行数为 628(a+b+c+d=e 段),其中 600(c 段)为 显示行;每行均有行同步信号(a 段),为 4 个行周期的低电平;

        列时序:每个显示行包括 1056 列(a+b+c+d=e 段),其中 800(c 段) 为有效显示区,每一行有一个行同步信号(a 段),为 128 个行周期的低电 平。

        如何确定将一行扫描完?

       需要根据显示标准规定的扫描时钟控制产生一个列计数器cnt_hs,扫描时钟为扫描一个像素点时钟;刷新时钟表示扫描完所有像素点的时间作为该时钟的周期。当列计数器计数到最大值时,表示当前行所有的像素点扫描完成。

如何确定将所有行扫描完成或者说将所有像素点扫描完?

       可以产生一个行计数器cnt_vs,其变化一次的条件为:列计数器计数到最大值,当列计数器等于最大值且行计数器等于最大值时,将所有的像素点扫描完成。

以显示标准为:640*480*60为例进行设计验证

       640表示有效显示区域的列数,480表示有效显示区域的行数,60hz表示刷新时钟,包含的像素点个数为:800*525,扫描一个像素点的时间为:(1/60)/(800*525),那么扫描一个像素点时钟频率为:800*525*60=25_200_000hz;

行计数器的最大值为:524,列计数器的最大值为:799

通过列计数器cnt_hs控制产生行同步信号vga_hs,当列计数器cnt_hs小于96时,行同步信号vga_hs等于0,其余值时等于1;

通过行计数器cnht_vs控制产生列同步信号vga_vs,将列同步信号称为场同步信号,,当行计数器cnt_vs小于2时,场同步信号vga_vs等于0,其余值时等于1;

        3.顶层架构

        调用锁相环产生时钟,vga_ctrl产生对应的场脉冲信号行脉冲信号,颜色数据。

        4.端口描述

clk板载时钟(50Mhz)
rst_n复位按键(低电平有效)
vga_hs行脉冲信号
vga_vs场脉冲信号
[7:0] vga_rgb颜色数据信号,高三位表示红色,
    中间三位表示绿色,低两位表示蓝色

二、代码验证

        vga_ctrl模块:产生对应的场脉冲信号行脉冲信号,颜色数据。

module vga_ctrl(

	input clk,
	input rst_n,
	
	output vga_hs,
	output vga_vs,
	output [7:0] vga_rgb
);

reg [9:0] cnt_hs;//列计数器
reg [9:0] cnt_vs;//行计数器
wire hs_en;//列有效显示区域
wire vs_en;//行有效显示区域
wire volid_en;//有效显示区域

always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt_hs <= 10'd0;
	else
		if(cnt_hs < 799)//行扫描
			cnt_hs <= cnt_hs + 10'd1;
		else
			cnt_hs <= 10'd0;
end 

always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt_vs <= 10'd0;
	else
		if(cnt_hs == 799)
			if(cnt_vs < 524)//列扫描,每行扫描完加1
				cnt_vs <= cnt_vs + 10'd1;
			else 
				cnt_vs <= 10'd0;
		else
			cnt_vs <= cnt_vs;
end 

assign vga_hs = (cnt_hs < 96)?1'b0:1'b1;//同步信号经过后拉低

assign vga_vs = (cnt_vs < 2)?1'b0:1'b1;//同步信号经过后后拉低

assign hs_en = ((cnt_hs > 143)&&(cnt_hs < 784))?1'b1:1'b0;

assign vs_en = ((cnt_vs > 34)&&(cnt_vs < 515))?1'b1:1'b0;

assign volid_en = hs_en & vs_en;//显示的有效区域

assign vga_rgb = (volid_en == 1)?8'b111_000_00:8'd0;

endmodule 

        vga_driver模块:顶层连线

module vga_driver(

	input clk,
	input rst_n,
	
	output vga_hs,//行脉冲信号,由列计数器控制产生
	output vga_vs,//场脉冲信号,由行计数器控制产生
	output [7:0] vga_rgb/*颜色数据信号,高三位表示红色,
	中间三位表示绿色,低两位表示蓝色*/
);

wire vga_clk;//25.2mhz
wire locked;

vga_pll	vga_pll_inst (
	.areset ( ~rst_n ),
	.inclk0 ( clk ),
	.c0 ( vga_clk ),
	.locked ( locked )
);

vga_ctrl vga_ctrl_inst(

			.clk(vga_clk),
			.rst_n(locked),
			
			.vga_hs(vga_hs),
			.vga_vs(vga_vs),
			.vga_rgb(vga_rgb)
);

endmodule 

仿真代码:

`timescale 1ns/1ps
module vga_driver_tb;

	reg clk;
	reg rst_n;
	
	wire vga_hs;
	wire vga_vs;
	wire [7:0] vga_rgb;

vga_driver vga_driver_instx(

			.clk(clk),
			.rst_n(rst_n),
			
			.vga_hs(vga_hs),//行脉冲信号,由列计数器控制产生
			.vga_vs(vga_vs),//场脉冲信号,由行计数器控制产生
			.vga_rgb(vga_rgb)/*颜色数据信号,高三位表示红色,
			中间三位表示绿色,低两位表示蓝色*/
);

initial clk = 0;
always #10 clk = ~clk;

initial begin
	rst_n = 0;
	#200
	rst_n = 1;
	#1000
	$stop;
end 

endmodule 

三、仿真验证

观察仿真波形图,在显示数据扫描完消隐区后,数据正常显示

参考资料

VGA接口

VGA显示原理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1976397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

普乐蛙VR航天科普展厅VR虚拟现实项目激发青少年对太空探索

普乐蛙品牌VR沉浸体验式业态&#xff0c;定位文旅科教领域&#xff0c;助力中国航天发展。普乐蛙VR航天航空主题拥有华夏神舟、天宫一号、华夏月球车、太空飞船、华夏方舟、地震平台、暴风空间等众多科普体验设备和原创优质的航天航空内容&#xff0c;通过沉浸互动式体验&#…

USB 2.0 规范摘录

文章目录 1、USB 体系简介2、USB 数据流模型四种传输类型 3、USB 物理规范和电气规范4、USB 协议层规范事务传输&#xff08;Transaction&#xff09;的流程 5、USB 框架6、USB 主机&#xff1a;硬件和软件7、USB HUB 规范数据的转发唤醒信号的转发USB HUB 的帧同步HUB Repeate…

11087 统计逆序对(优先做)

这个问题可以通过使用分治策略来解决&#xff0c;这种策略是在归并排序的基础上进行的。我们可以将数组分为两部分&#xff0c;然后分别计算两部分的逆序对数量&#xff0c;最后计算跨越两部分的逆序对数量。 以下是使用C的代码实现&#xff1a; #include <iostream> #…

C++初学者指南-5.标准库(第二部分)--更改元素算法

C初学者指南-5.标准库(第二部分)–更改元素算法 文章目录 C初学者指南-5.标准库(第二部分)--更改元素算法填充/覆盖范围fill / fill_ngenerate / generate_n 更改/替换值transformreplace / replace_ifreplace_copy / replace_copy_if 相关内容 不熟悉 C 的标准库算法&…

【数据泄露】最新 FBI 官员数据库泄露事件

前言 近日&#xff0c;一名化名为 “rpk” 的威胁行为者在 breachforums 论坛上声称泄露了包含 22,175 名 FBI 官员数据的数据库。此事件迅速引起了广泛关注&#xff0c;主要因为 FBI 作为美国联邦调查局&#xff0c;不仅是美国司法部的主要调查机构&#xff0c;还是美国情报界…

太离谱!曝 GPT-4o mini 没做安全测试就开庆功会!OpenAI 严重违背政府协议,被立法者犀利追问 12 条

OpenAI又被曝违约了!这次是违反了对白宫的安全承诺。 去年夏天,OpenAI向美国政府承诺,将严格对其前沿的突破性技术进行安全测试,以确保AI不会造成损害,比如教用户制造生化武器或帮助黑客开发新型网络攻击。 然而,为了应对OpenAI领导层设定的GPT-4o mni 5月份的“deadli…

RabbitMQ高级特性 - 消息分发(限流、负载均衡)

文章目录 RabbitMQ 消息分发概述如何实现消费分发机制&#xff08;限制每个队列消息数量&#xff09;使用场景限流背景实现 demo 非公平发送&#xff08;负载均衡&#xff09;背景实现 demo RabbitMQ 消息分发 概述 RabbitMQ 的队列在有多个消费者订阅时&#xff0c;默认会通过…

MySQL —— 库,数据类型 与 表

库与基础操作 1.1 查看数据库 使用 show databases; 可以查看当前 MySQL 目前有多少个数据库 5 rows 表示有 5 行&#xff0c;这里是表示的是有效的数据&#xff0c;不包括 第一行的指引 set 表示结果集合 0.01 sec 表示这个 sql 语句一共运行了0.01 秒&#xff0c;一般情况…

【多线程】线程的五种创建方法

文章目录 线程在 Java 代码中编写多线程程序Thread 标准库 创建线程的写法1 . 继承 Thread 类代码回调函数休眠操作&#xff1a;sleep()抢占式执行观察线程jconsoleIDEA 内置调试器 2 . 实现 Runnable 接口代码 3. 匿名内部类创建 Thread ⼦类对象代码匿名内部类 4.匿名内部类创…

Python数据分析案例57——信贷风控模型预测评估及其可解释性(shap, scorecardpy包应用)

案例背景 在信贷风控场景下&#xff0c;其实模型的可解释性就变得很重要。在平时做一些普通的机器学习的案例的时候&#xff0c;我们根本不关心这些变量是怎么究竟影响到模型最后的决策的&#xff0c;随便直接把数据丢进去&#xff0c;再把要预测的数据丢进去就能出结果。但是…

Rabbitmq的几种工作模式

工具类 public class RabbitMQConnection {public static Connection getConnection() throws Exception{//1.创建connectionFactoryConnectionFactory connectionFactory new ConnectionFactory();//2.配置HostconnectionFactory.setHost("127.0.0.1");//3.设置Po…

kafka从浅入深

一、什么是kafka&#xff1f; kafka本质上是一个消息队列MQ&#xff08;Message Queue&#xff09;&#xff0c;用做数据流转。 1.使用消息队列的好处&#xff1f; 1.1、解耦&#xff1a;允许独立扩展或修改队列两头的处理过程&#xff1b; 1.2、可恢复性&#xff1a;即使一个…

Unity 资源之 Break Items - Toon VFX破碎物品与卡通硬币动画分享

Unity 特效资源分享 - 破碎物品与卡通硬币动画 一、前言二&#xff0c;资源包内容三、免费获取资源包 一、前言 今天为大家带来一份超级实用的视觉特效资源分享&#xff01;我们精心整理了 6 个令人惊叹的破碎物品效果和 1 个萌趣十足的卡通硬币动画视觉特效&#xff0c;让您的…

编译和汇编的区别

一、编译 编译是将高级语言&#xff08;如C、C、Java等&#xff09;编写的源代码转换成计算机可以直接执行的低级语言&#xff08;通常是机器语言或汇编语言&#xff09;的过程 编译 —— 将人类可读的源代码转换为计算机可执行的指令集 编译过程 通常包括词法分析、语法分…

bootloader开发总结

bootloader开发总结 首先明白了BootLoader和应用程序之间跳转&#xff0c;就明白了大概。上电启动程序&#xff0c;会有一个程序入口&#xff0c;这个入口由0x33fff6(28335的)地址决定。 应用程序也会有一个启动入口&#xff0c;这个用户可以自己决定。 bin文件是高地址在前&a…

【数据结构】非线性表----二叉树详解

二叉树与普通的树的本质上的区别实际上只有一个——子结点的数量。 普通的树&#xff1a;任意数量的子结点 二叉树&#xff1a;只有两个子结点&#xff0c;也称为左孩子和右孩子结点。 二叉树一共有五种形态&#xff1a; 1.空二叉树。 2.只有一个根结点。 3.根结点只有左子树…

【OpenCV C++20 学习笔记】图像缩放-高斯金字塔

图像缩放-高斯金字塔 原理高斯金字塔 代码实现放大缩小形成金字塔 原理 在图像处理中&#xff0c;经常需要将图像转化成不同的尺寸&#xff0c;即放大或缩小。 除了直接用resize()函数重新设置图片尺寸&#xff0c;另一种常用的方法就是“图像金字塔”。 图像金字塔是从底层的…

vector的底层原理剖析及其实现

vector 一、定义二、常用接口及模拟实现三、vector迭代器失效问题四、使用memcpy拷贝会出现的问题五、二维数组vector<vector< T >> vv 一、定义 vector 是 C 标准模板库&#xff08;Standard Template Library, STL&#xff09;中的一个非常有用的容器。它是一个…

23款奔驰GLS450加装原厂电吸门配置,提升车辆舒适性和便利性

今天是一台22款奔驰GLS450&#xff0c;车主是佛山的 以前被不良商家坑了 装了副厂的电吸门 刚开始就很正常 用了半年之后 就开始开不了门&#xff0c;被锁在里面&#xff0c;刚开始车主以为是零件坏了 后来越来越频繁&#xff0c;本来是为了家里老人小孩关门方便而升级的&#…

J031_使用TCP协议支持与多个客户端同时通信

一、需求文档 使用TCP协议支持与多个客户端同时通信。 1.1 Client package com.itheima.tcp2;import java.io.DataOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner;public class Client {public static void main(String[] a…