VGA实验总结(屏保显示效果)

这个程序中含图像位置移动控制部分,可控制图像在屏幕范围内成45°角移动,撞到边缘后改变方向,类似于屏保的显示效果。这篇随笔主要就是要记录一下我对于这个功能代码的理解。

 

 

 

 

 

 上面这两张图片中的代码就是实现图片移动的主要代码。这段教程来自王金明编写的数字系统设计与VERILOG HDL,但感觉这里面有点错误,所以不仔细讲解。

第一张图中描述的是显示图片的大小(长与宽的限制),第二张图则描述的是一帧图像的开始位置。第二张图片的功能可以先从ALWAYS的触发条件下手,是VS的下降沿。VS的下降沿标志着前一帧图像的结束和下一帧图像的开始,说明这段程序每显示一帧就只仅执行一次。ij的四个值代表着四种运动方向,xpos与ypos的值应该为每一帧显示图像的第一个像素的位置。每一次进入这段程序,起始地址就会发生一次变化,知道图片运动到边界地址(即起始像素的地址加上图片的尺寸后与显示的有效区域边界地址相同),那么就需要转换另一种方向。根据这一张图片中的代码可知,图片是不会运动到显示有效区域之外的,这一点对于第一张图片中代码的理解是非常重要的。

根据前面所说的第一张图片所代表的意义,我们可以推断出,对于列的计数,必须要计到进入有效区并且扫到这一帧图像的起始地址,这是起点;而终点就是起点+图片大小中的长度。根据上面提及的东西可知,这个终点是不会在有效显示区域之外的。同理,行的计数也是如此设置的。但图片中给出的列的计数的判断条件并没有体现进入有效区(只有TA并不能说明进入有效区,个人觉得应该是TA+TB+TC,行的计数的判断条件是正确的(需要有判断是否进入有效区的数字,如TA+TB+TC,这个数字说明已经在有效区扫描,但不需要判断是否出有效区的数字,因为图片根本不会在有效区之外

经过前面的学习,已经知道了VGA的显示主要分为pll、同步模块和控制模块,应该是这两个名称吧。同步模块是按照显示模式的不同进行列计数、行计数.有的教材中把HS称为行同步,把VS称为场同步;有的教材则称HS为列同步,把VS称为行同步。虽然名称不尽相同,但表达的意思是一样的。HS是对列进行计数,其时序图中的高电平代表着一行(所有列)像素点的扫描;VS则是对行进行计数,一段高电平(所有行)就代表一帧图像的扫描。所以说,HS时序中的上升沿就代表着一行的结束,另一行的开始;VS中的下降沿代表着一帧的结束,另一帧的开始。

另外,想对下面这几行描述VGA消隐信号和同步信号(注意,这个同步信号与HS、VS没有关系),暂时没有找到这个同步信号和消隐信号确切的时序表

后面找到另一本教材,里面赞同的是虚线上面这个代码表示,而且说明这个BLANK并不是消隐信号,而是行或场同步输出有效信号。总之,这个信号是需要传给VGA DAC的。另外那个不知是否为同步信号的信号到底起什么作用,其值应该为多少是不知道的。在两本教材中,只有其中一本上列了这个信号,在网上找的例子上也有这个信号,在黑金教程中没有类似的信号,所以需不需要是不确定的。

assign hsync= (count_h<10'd96)?1'b0:1'b1;   //这描叙的是行、列同步信号的值
assign vsync= (count_v<10'd2)?1'b0:1'b1;

assign sync_n=1'b0;//由FPGA传给VGA DAC的VGA_SYNC_N
assign blank_n=hsync && vsync;//由FPGA传给VGA DAC的VGA_BLANK_N //根据行列同步信号计算出的消隐信号的取反值,由此可以推出,消隐信号为行同步信号取反+帧同步信号取反(即两者只要有一个消隐,即为消隐)

--------------------------------
assign ovga_sync=1'b1;
assign ovga_blank=~((h_cont<H_BLANK)||(v_cont<V_BLANK)); //而这个表达式则是直接根据行列时序来得出消隐值的,根据A+B的非等于A非&&B非:ovga_blank=(h_cont>=H_BLANK)&&(v_cont>=V_BLANK)
这两个表达式最终的结果都要经过取反再传给VGA DAC
这个表达式与前面这个表达式的差别是,上面那个表达式认为,只要是行列同步信号其中一个为低电平,那就是消隐。而下面这个表达式由于H_BLANK的值为非有效区像素个数的半部分的值,V_BLANK也是,所以下面这个表达式大概认为,
非显示有效区的都是消隐区。
 

--------------------------------------------------------------------- 

下面再讲解一下对于https://www.cnblogs.com/tony1224/archive/2011/11/09/2243603.html这篇博文的理解。

博主说的很详细,我只是在根据自己的理解加深巩固。图片的大小为224*32,224个列像素,32个行像素。该图片的像素数据在ROM中是按列存储的,ROM为32位宽,深度为224.第一列对应着ADDR=0的数据。

那么如何将数据取出来并重现图片呢?可以这样理解:ROM按列存储,且从高到低存储,所以224个ROM的最高位rom_data[31]就对应着图片的第一行,显示器是按逐行逐列扫描,先扫第一行的第一列,所以需要先访问ADDR=0的rom_data[31],然后再是第一行的第二列,访问的是ADDR=1的rom_data[31].ADDR从0~224循环计数,循环一遍就扫完一行的像素。扫完一行,y就加一,然后就取的是每一个rom_data[30]。因此,可以得出rom_data[Y]中Y应该是(y为行的计数):0行(相对于有效区的行标)------31  1行(有效区的行标)--------30    可以得出Y=31-有效行标,而有效区行标=y-40(40=v_ta+v_tb+v_tc   y坐标对应显示的开始点位y=40);因此Y=71-y;

另外,这篇博文还提及了各个模块之间传输数据要消耗一个时钟的说法,所以要提前各个时钟传输数据,有的教材上也有一点,没有着重介绍,以后遇到再说。

 

posted @ 2020-02-27 17:29  cnmdxiaoxn  阅读(790)  评论(0)    收藏  举报