FPGA 学习笔记(十一) VGA驱动的实现
VGA时序图
1)行扫描时序图
a:行同步时期,扫描地址的复位
b:行消隐后肩,扫描地址转移后的稳定等待准备期
c:行显示时期,数据有效区域
d:行消隐前肩,扫描地址转移的准备
e:行扫描总时间,一行扫描的总时间
2)场扫描时序图
o:场同步时期,扫描地址的复位
p:场消隐后肩,扫描地址转移后的稳定等待准备期
q:场显示时期,数据有效区域
r:场消隐前肩,扫描地址转移的准备
s:场扫描总时间,一场扫描的总时间
3)VGA显示器扫描轨迹
常见的刷新率时序表
由于FPGA擅长计数电路这里采用像素表示法来设计驱动
FPGA硬件 测试时要将sys_pll中的输出频率改为25MHZ。
驱动电路的verilog设计(lcd_driver)
由亍目前液晶显示器的普及,而高于 60Hz 的刷新率对于液晶来说,没有任何意义,所以我们以 640*480 在 60Hz 的刷新率下为例。
本次我们采用的是ADV7123视频转换芯片来实现。
1)为便于移植,根据640*480 60hz分辨率下的参数,宏定义相关数据
//---------------------------------
// 640 * 480
`define H_FRONT 11'd16
`define H_SYNC 11'd96
`define H_BACK 11'd48
`define H_DISP 11'd640
`define H_TOTAL 11'd800 `define V_FRONT 11'd10
`define V_SYNC 11'd2
`define V_BACK 11'd33
`define V_DISP 11'd480
`define V_TOTAL 11'd525
2)行扫描单位hcnt计数
/*******************************************
SYNC--BACK--DISP--FRONT
*******************************************/
//------------------------------------------
//h_sync counter & generator
reg [10:0] hcnt;
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
hcnt <= 11'd0;
else
begin
if(hcnt < `H_TOTAL - 1'b1) //line over
hcnt <= hcnt + 1'b1;
else
hcnt <= 11'd0;
end
end
assign lcd_hs = (hcnt <= `H_SYNC - 1'b1) ? 1'b0 : 1'b1;
//VGA行同步信号
3)列扫描单位vcnt计数
每扫描完一行,即hcnt完成H_TOTAL次计数后,vcnt进行自加。
//------------------------------------------
//v_sync counter & generator
reg [10:0] vcnt;
always@(posedge clk or negedge rst_n)
beginif (!rst_n)vcnt <= 11'b0;else if(hcnt == `H_TOTAL - 1'b1) //line overbeginif(vcnt < `V_TOTAL - 1'b1) //frame overvcnt <= vcnt + 1'b1;elsevcnt <= 11'd0;end
end
assign lcd_vs = (vcnt <= `V_SYNC - 1'b1) ? 1'b0 : 1'b1;
//VGA场同步信号
4)ADV7123控制信号输出
为了实现数据在lcd_dclk上升沿有效,我们将clk翻转输出,已实现上升沿采样
lcd_blank作为显示空白信号,低电平有效。
设计中不需要lcd_sync信息,可以直接接地。
//------------------------------------------
//LCELL LCELL(.in(clk),.out(lcd_dclk));
assign lcd_dclk = ~clk;
assign lcd_blank = lcd_hs & lcd_vs;
assign lcd_sync = 1'b0;
5)有效显示使能信号输出
当使能信号有效时,接收外部输入的RGB数据lcd_data.
//-----------------------------------------
assign lcd_en = (hcnt >= `H_SYNC + `H_BACK && hcnt < `H_SYNC + `H_BACK + `H_DISP) &&(vcnt >= `V_SYNC + `V_BACK && vcnt < `V_SYNC + `V_BACK + `V_DISP)
? 1'b1 : 1'b0;
assign lcd_rgb = lcd_en ? lcd_data : 24'h000000; //ffffff;
6)外部数据请求控制信号。
为了实现数据的稳定,lcd_request要提前一个时钟请求外部输入数据
同时,设计中实时显示下一时刻的扫描地址lcd_xpos、lcd_ypos,也要提前一个时钟输出,以保证外部数据输入的同步化。
lcd_xpos、lcd_ypos作为显示器有效显示区域的行列坐标计数值。
//------------------------------------------
//ahead x clock
localparam H_AHEAD = 11'd1;
assign lcd_request = (hcnt >= `H_SYNC + `H_BACK - H_AHEAD && hcnt < `H_SYNC + `H_BACK + `H_DISP - H_AHEAD) &&(vcnt >= `V_SYNC + `V_BACK && vcnt < `V_SYNC + `V_BACK + `V_DISP) ? 1'b1 : 1'b0;
//lcd xpos & ypos
assign lcd_xpos = lcd_request ? (hcnt - (`H_SYNC + `H_BACK - H_AHEAD)) : 11'd0;
assign lcd_ypos = lcd_request ? (vcnt - (`V_SYNC + `V_BACK)) : 11'd0;
模拟VGA图像数据的输入
1)宏定义三原色组合的颜色如下
//define colors RGB--8|8|8
`define RED 24'hFF0000 /*11111111,00000000,00000000 */
`define GREEN 24'h00FF00 /*00000000,11111111,00000000 */
`define BLUE 24'h0000FF /*00000000,00000000,11111111 */
`define WHITE 24'hFFFFFF /*11111111,11111111,11111111 */
`define BLACK 24'h000000 /*00000000,00000000,00000000 */
`define YELLOW 24'hFFFF00 /*11111111,11111111,00000000 */
`define CYAN 24'hFF00FF /*11111111,00000000,11111111 */
`define ROYAL 24'h00FFFF /*00000000,11111111,11111111 */
这里要注意你所用的VGA驱动电路是RGB888还是RGB565,若是RGB565,三原色要改成下面样式,并把其他程序中lcd_data的位数改为16位:
笔者曾在这里犯过错误。
//define colors RGB--5|6|5
`define RED 16'hF800 /*11111111,00000000,00000000 */
`define GREEN 16'h07E8 /*00000000,11111111,00000000 */
`define BLUE 16'h0011 /*00000000,00000000,11111111 */
`define WHITE 16'hFFFF /*11111111,11111111,11111111 */
`define BLACK 16'h0000 /*00000000,00000000,00000000 */
`define YELLOW 16'hFFE0 /*11111111,11111111,00000000 */
`define CYAN 16'hF81F /*11111111,00000000,11111111 */
`define ROYAL 16'h07FF /*00000000,11111111,11111111 */
2)根据输入的行、列地址信号,输出三原色组合后得到的8条彩色。
//-------------------------------------------
`ifdef VGA_HORIZONTAL_COLOR
always@(posedge clk or negedge rst_n)
beginif(!rst_n)lcd_data <= 24'h0;elsebeginif (lcd_ypos >= 0 && lcd_ypos < (`V_DISP/8)*1)lcd_data <= `RED;else if(lcd_ypos >= (`V_DISP/8)*1 && lcd_ypos < (`V_DISP/8)*2)lcd_data <= `GREEN;else if(lcd_ypos >= (`V_DISP/8)*2 && lcd_ypos < (`V_DISP/8)*3)lcd_data <= `BLUE;else if(lcd_ypos >= (`V_DISP/8)*3 && lcd_ypos < (`V_DISP/8)*4)lcd_data <= `WHITE;else if(lcd_ypos >= (`V_DISP/8)*4 && lcd_ypos < (`V_DISP/8)*5)lcd_data <= `BLACK;else if(lcd_ypos >= (`V_DISP/8)*5 && lcd_ypos < (`V_DISP/8)*6)lcd_data <= `YELLOW;else if(lcd_ypos >= (`V_DISP/8)*6 && lcd_ypos < (`V_DISP/8)*7)lcd_data <= `CYAN;else// if(lcd_ypos >= (`V_DISP/8)*7 && lcd_ypos < (`V_DISP/8)*8)lcd_data <= `ROYAL;end
end
`endif
不同分辨率的VGA驱动
lcd_para文件定义了四种VGA分辨率驱动,这里只需修改定义的注释就行,并把PLL锁相环中的频率改为相应的频率。
//`define VGA_640_480_60FPS_25MHz
//`define VGA_800_600_72FPS_50MHz
//`define VGA_1024_768_60FPS_65MHz
`define VGA_1280_1024_60FPS_105MHz
PLL修改方法为直接修改下面参数中的乘法除法因子:
altpll_component.clk0_divide_by = 10,altpll_component.clk0_duty_cycle = 50,altpll_component.clk0_multiply_by = 21,altpll_component.clk0_phase_shift = "0",altpll_component.compensate_clock = "CLK0",altpll_component.inclk0_input_frequency = 20000,
FPGA 学习笔记(十一) VGA驱动的实现相关推荐
- 小梅哥FPGA学习笔记
小梅哥FPGA学习笔记 一.38译码器 功能: 译码器其任一时刻的稳态输出,仅仅与该时刻的输入变量的取值有关,它是一种多输入多输出的组合逻辑电路,负责将二进制代码翻译为特定的对象(如逻辑电平等).38 ...
- FPGA学习笔记(十二)IP核之FIFO的学习总结
系列文章目录 一.FPGA学习笔记(一)入门背景.软件及时钟约束 二.FPGA学习笔记(二)Verilog语法初步学习(语法篇1) 三.FPGA学习笔记(三) 流水灯入门FPGA设计流程 四.FPGA ...
- FPGA学习笔记(五)Testbench(测试平台)文件编写进行Modelsim仿真
系列文章目录 一.FPGA学习笔记(一)入门背景.软件及时钟约束 二.FPGA学习笔记(二)Verilog语法初步学习(语法篇1) 三.FPGA学习笔记(三) 流水灯入门FPGA设计流程 四.FPGA ...
- FPGA学习笔记_Quartus II_In system sources and probes editor(ISSP)调试工具的使用
FPGA学习笔记 Quartus II prime Standard Edition-In system sources and probes editor(ISSP)调试工具的使用 Quartus ...
- Apache Nutch 1.3 学习笔记十一(页面评分机制 OPIC)
1. Nutch 1.3 的页面评分机制 Nutch1.3目前默认还是使用OPIC作为其网页分数算法,但其之后,已经引入了PageRank-like算法,以弥补OPIC算法的不足,目前OPIC算法还是 ...
- FPGA学习笔记之Altera FPGA使用JIC文件配置固化教程
FPGA学习笔记之Altera FPGA使用JIC文件配置固化教程 很多做过单片机的朋友都知 道,我们在对MCU烧写完程序固件后,那么该程序固件就存储在了该MCU内部.即使MCU断电了再重新上电,程序 ...
- 吴恩达《机器学习》学习笔记十一——应用机器学习的建议
吴恩达<机器学习>学习笔记十一--应用机器学习的建议 一.训练完模型后下一步要做什么 二.评估算法与模型选择 1.训练集与测试集 2.训练/测试步骤 3.模型选择 4.数据集新的划分--验 ...
- 吴恩达《机器学习》学习笔记十一——神经网络代码
吴恩达<机器学习>学习笔记十一--神经网络代码 数据准备 神经网络结构与代价函数· 初始化设置 反向传播算法 训练网络与验证 课程链接:https://www.bilibili.com/v ...
- ROS学习笔记十一:ROS中数据的记录与重放
ROS学习笔记十一:ROS中数据的记录与重放 本节主要介绍如何记录一个正在运行的ROS系统中的数据,然后在一个运行的系统中根据记录文件重新产生和记录时类似的运动情况.本例子还是以小海龟例程为例. 记录 ...
- Apache Nutch 1.3 学习笔记十一(页面评分机制 LinkRank 介绍)
下面是Google翻译的http://wiki.apache.org/nutch/NewScoring内容,是关于Nutch 新的链接分数算法的说明,有点类似于Google的PageRank,这里有其 ...
最新文章
- 【组合数学】生成函数 ( 求和性质 )
- 中国牙科用人工骨替代材料市场供需态势与未来投资方向分析报告2022年
- mysql---视图
- 雨棚板弹性法计算简图_钢结构工程量计算4点注意事项,还不来看?
- graphql 有必要吗_您准备好观看GraphQL了吗?
- Linux 终端仿真程序Putty
- ruby array_Ruby中带有示例的Array.fill()方法(3)
- 02-02 Python 读写文件 open|os|sys
- 5G 爆发前夕,将渗透哪些领域?
- 用VB编写的一个可在屏幕上移动的十字架
- 剑指OFFER之用两个栈实现队列(九度OJ1512)
- 有状态容器实践:k8s集成ceph分布式存储
- 约束理论学习随笔(1)
- ionic入门教程第十一课-简要说明ion-list、ion-item完成列表页ion-infinite-scroll上拉加载ion-refresher下拉刷新
- mac 开机启动php,macbook开机启动nginx和php
- Python爬虫《自动化学报》数据爬取与数据分析
- Mysql连接数据库url的参数解析
- python中的继承的初始化_python中子类继承父类的__init__方法实例
- python tell_Python 文件 tell() 使用方法及示例
- ORACLE序列的作用