现在的位置: 首页 > 综合 > 正文

【连载】【FPGA黑金开发板】Verilog HDL那些事儿–VGA(二十)

2012年03月22日 ⁄ 综合 ⁄ 共 3795字 ⁄ 字号 评论关闭

声明:本文为原创作品,版权归akuei2及黑金动力社区(http://www.heijin.org)共同所有,如需转载,请注明出处http://www.cnblogs.com/kingst/

2


5.6 实验十九:VGA封装

在笔者还没有开始写这本笔记之前,笔者和大众的新手一样,都喜欢在网络上找资料。

有一篇论文“基于FPGAVGA接口”中的实验,笔者很感兴趣,但是论文始终是论文,论文的东西都是用来毕业,瞎了笔者的狗眼。笔者就在那个时候开始突发奇想:“有没有什么的办法,以最小的条件,来实验该论文中的内容呢?

在此刻,阅读这章笔记的时候,读者是否对“封装”或者“接口”有一个概念了吧?

同样的事实,VGA模块也需要封装成为VGA接口。

clip_image002

 

上图是组合模块 vga_interface.v ,里面包含了“同步模块”(用于配置显示标准,和驱动VGA),“VGA控制模块”(用于控制图像信息),还有一个双向RAM模块。是不是觉得很疑惑:为什么多了一个RAM模块出来。

 

在实验九中,VGA控制模块读取的图片信息是来自ROM模块。相反的实验十九的图像信息是来自RAM。在完成VGA接口之前,我们必须设定一些参数。

图像分辨率

16 x 16

图像颜色

点阵

图像显示位置

X = 3 Y = 2

显示标准

800 x 600 x 60Hz

 

显示标准,关于这个参数,在3.4章中有详细的介绍,这里就重复了。图像分辨率,说简单点就是一副图像信息的大小。图像颜色,点阵的意思就是黑和白。图像显示位置,是指一副图信息开始显示的位置,X = 3 Y = 2,表示图像在屏幕的坐标(3, 2)显示。

sync_module.v

clip_image004


clip_image006

sync_module.v 是支持 800 x 600 x 60Hz 的显示标准(需要40Mhz的时钟源)。

vga_control_module.v

clip_image008


clip_image009

29行的if条件,就是表示开始显示位置 Y 39行的开始显示位置 X

我们知道图像信息是16 x 16。所以,29行的if条件成立范围是在 Row_Addr_Sig > 1 ~ Row_Addr_Sig < 17。同样的在39行的if条件成立范围在 Column_Addr_Sig > 2 ~ Column_Addr_Sig < 19

 

24行和34行的寄存器mn,是用来列寻址和行寻址。所以它们必须从“开始显示位置”开始计数。

 

46~54行的isSize标志寄存器是用来确定“一副图像的显示框”,亦即“图像显示有效范围”。在51~52行的if条件指定了该isSize表示寄存器被拉高的时候,也就是说在Row_Addr_Sig > 1 ~ Row_Addr_Sig < 17 Column_Addr_Sig > 2 ~ Column_Addr_Sig < 19,分辨率为 16 x 16 的图像时“显示有效”的。

 

59行表示m行寻址 等价于Ram_Addr 地址。

 

61~63行,是列寻址,同是点阵操作。由于该VGA接口的颜色支持参数是“黑白”的缘故,所以61~63行都是同样的点阵操作。

ram_module.v

 

clip_image011

 

RAM是什么,有电子背景的同学都知道它是什么。RAMROM不同的是,RAM支持访问(读和写操作),然而ROM只支持读操作。一般上RAM有分为单端口,双向端口,三向端口。双向端口,有为分为真双向端口(True),和假双向端口(Simple),真双向端口有写入时钟和读取时钟,然而假双向端口读写共用一个时钟。为了方便vga_interface.v 的建模,在这里我们使用假双向端口RAM

在这里,我们先要考虑 vga_interface.v 支持的图像分辨率,亦即 16 x 16 。所以RAM所需要的储存空间是 16Bits x 16 WordsRAM FIFO一样,要访问RAM的时候都需要拉高 xx_En_Sig 信号。由于RAM 包含 16 Bits 所以 Write_Data Read_Data, 皆是16位的位宽。当然,16 Words 表示了 xx_Addr_Sig 4位的位宽。

 

一个普遍存在与双向端口RAM的问题是“同时读写冲突”。一般的物理双向端口RAM都内置仲裁逻辑。“仲裁逻辑”的设计方法是比较复杂,我们使用另一种方法,就是“访问优先级”。

 

在这里,我们可以这样定义:写操作的优先级高于读操作。

 

所以呀,使用QuartusII 自建的双向端口RAM不怎么适合。换一句话,我们必须手动创建包含“访问优先级”的“假双向端口RAM”。

clip_image013


clip_image014

1~11行是RAM模块的输入输出口。在15行,声明了 16Bits x 16 Words 的储存器。

如果以AlteraFPGA为例,尝试回想一下,FPGA都内置了偏上资源 m4k。当我声明储存器的时候,我们可以指定它由 m4k 组成。

* ram_tyle = m4k *

当然你也可以指定储存器由逻辑资源组成:

* ram_tyle = logic *

在前面,我已经说过:“双向端口的RAM存在访问冲突的问题”。当QuartusII 在综合的时候,由于 m4k 资源本身的特性,并不适合“写时读”(read-during-write),亦即“访问冲突”。虽然,我们手动为RAM模块添加了访问优先级,可以避免“访问冲突”的问题。但是Quartus II 的综合器是一个大笨蛋,你没有提示它:“不用关心m4k资源的访问冲突问题”,综合器是不知道的。因此:

* ram_style = no_rw_check *

还有一点就是关于储存器初始化的问题:

还记得在建立ROM的时候,笔者都为ROM建立一个 .mif ,然后对ROM初始化。同样的道理,RAM储存器在创建的时候也必须初始化。该RAM模块初始化的信息,是实验十之五之中的“第一副小绿人”。

* ram_init_file = ram_initial_file.mif *

21~27行是RAM模块的访问优先级逻辑。在24行表示了写操作比读操作拥有更高的优先级。当 Write_En_Sig 拉高的时候,对RAM储存器执行写操作。一旦 Write_En_Sig 被拉低 读操作作为RAM储存器的默认状态。

有一重点必须注意就是rData寄存器是用来暂存读数据。为了避免“当写操作执行时Read_Data 失去驱动源”。

vga_interface.v

clip_image016


clip_image017

 

VGA接口的时钟源是由全局时钟源经过倍频后输入的(9行)。

实验十九说明:

读者是不是觉得实验十九和实验九相比,简直是莫名其妙对吧?在这里笔者稍微区分一下实验九和实验十九的不同。实验九顾名思义就是VGA显示模块,它所使用的显示方法是同步的。换句话说,也就是图片信息处理和VGA显示驱动都是在同样的时间下。当然也可以这样想,图片信息是又VGA模块本身提供的,又或者图片信息早已固定存在。

 

实验十九的VGA接口, 恰好是与实验九的VGA显示模块相反。它所使用的显示方法是异步的。也就是说,图像信息处理和VGA显示驱动是在不同的时间下完成。看得简单点就是,图像信息是由外部提供。

 

在实验十九中的VGA接口,图像信息是暂存在RAM模块里,而且RAM模块里边的图像信息是由上一层模块写入。读者可能会产生这样一个问题:“假设vga_control_module.v 在读取RAM,地址0的信息的时候,生一层模块同时对RAM,地址0执行写操作 ...”。

事实上,由于访问优先级逻辑的关系,当发生“访问冲突”的时候,vga_control_module.v读取的是 上一次的rData信息。

 

读者可能又会问:“当发生访问冲突的时候,rData暂存的数据当然不是当前的显示数据,图像显示既不是出现错误?”。 你知道吗? LCD显示技术为了消除LCD显示残影的问题,在指定间隔时的间里,都会插入诺干“黑帧”(全黑图像信息)。如果LCD插入“黑帧”,已不是屏幕忽然间全黑,然后又恢复,又全黑,又恢复 .... 呵呵!事实上,人体的视觉是很蛋疼和迟钝的,这些“短暂”的“黑帧”人眼是察觉不出来。这也使得LCD消除残影的方法。

 

同样的道理,以800 x 600 x 60Hz 为显示标准。如果在1秒内出现 1~16个残缺的帧,人眼是不会察觉到,因为该显示标准时每秒60帧图像。用动画的话来说,每秒8帧产生拖尾效果,每秒24帧产生专业动画效果,每秒40帧人眼是“瞬间”的效果。

 

完成后的扩展图:

clip_image002

 

实验十九结论:

实验九和实验十九最大的差别就是图像信息处理的方法。前者是由模块内部提供的,后者是由上一层模块写入。此外实验十九当 vga_control_module.v ram_module.v 读取信息的时候,如果在同一个时间,上一层模块对 vga_interface.v ram_module.v 执行写操作,故会发生“访问冲突”。为了避免这个问题,笔者对 ram_module.v 加入了访问优先级逻辑,访问优先级定义为:写操作优先级高于读操作。

 

还有有关“实验十九说明”中提及种种“显示问题”会在“实验十九演示”中演示。

实验十九演示:小绿人请加油

clip_image004

 

上图的 vga_interface_demo.v 组合模块表示了,控制程序从 ROM模块读取图片信息,然后写入 VGA接口。该ROM模块是基于实验九之五的 greenman_rom_module.v ,里边包含了6 16 x 16 的图片信息。控制程序,每隔250ms写入不同的信息至VGA接口。所以在屏幕的显示结果上,会出现小绿人的动画。

vga_interface_demo.v

clip_image006


clip_image007

 

clip_image008

 

16~20行实例化了pll模块,pll模块将全局时钟倍频至40Mhz24行是

抱歉!评论已关闭.