方法1的缺点在于存储的数据量太大。一帧数据仅Y分量就是8bit*720*525 =3024000bit = 378KB,这个数据是不适合在SRAM中操作的,需要使用SDRAM,而操作SDRAM 是比较复杂的,所以一般考虑使用方法2,因为它需要很小的空间,而且可以利用FPGA的片内资源就可以实现。当图像数据传输很快的时候,人眼基本上是分不清奇偶场信号的,所以方法2是可行的。在讲方法2之前,需要了解在流水线操作中经常使用的乒乓操作,这是可编程逻辑常用的设计思想和技巧。乒乓操作常常应用于数据流控制,典型的乒乓操作如图5所示[3][4]。
图5 乒乓操作示意图
乒乓操作的处理流程描述如下:输入数据流通过“输入数据流选择单元”,等时地将数据流分配到两个数据缓冲模块。数据缓冲模块可以是任何存储模块,比较常用的存储单元是双口RAM ( DPRAM ),单口RAM ( SPRAM)和FIFO等。在第一个缓冲周期,将输入的数据流缓存到“数据缓冲模块1”。在第2个缓冲周期,通过“输入数据流选择单元”的切换,将输入的数据流缓存到“数据缓冲模块2”,与此同时,将“数据缓冲模块1”缓存的第1个周期的数据通过“输出数据流选择单元”的选择,送到“数据流运算处理模块”被运算处理。在第3 个缓冲周期,通过“输入数据流选择单元”的再次切换,将输入的数据流缓存到“数据缓冲模块1”,与此同时,将“数据缓冲模块2”缓存的第2个周期的数据通过“输出数据流选择单元”的选择,送到“数据流运算处理模块”被运算处理。如此循环,周而复始。
乒乓操作的最大特点是,通过“输入数据流选择单元”和“输出数据流选择单元”按节拍、相互配合的切换,将经过缓冲的数据流没有时间停顿地送到“数据流运算处理模块”,被运算和处理。把乒乓看成一个整体,站在这个模块的两端看数据,输入数据流和输出数据流都是连续不断的,没有任何停顿,因此非常适合对数据流进行流水线式处理。所以乒乓方式常常应用于流水线式算法,完成数据的无缝缓冲与处理。
在FPGA里面,使用乒乓操作是面积与速度互换原则的一个体现。
方法2 可以这样实现:在FPGA内部使用Megacore,构造一个双口的RAM, 双口RAM 的输入输出信号的硬件描述语言定义如下:
RAM2 u (.data_a (iDATA [7:0]) ,
.wren_a (I_a ) ,
.address_a(COUNTER_a [9 : 0] ) ,
.cLOCk_a ( CLOCK_ a) ,
.q_a(DATA_a [ 7 : 0 ] ) ,
.data_b(iDATA[7:0]),
.wren_b (I_b),
.address_b(COUNTER_b[9:0]) ,
.clock_b(CLOCK_b) ,
.q_b(DATA_b[7:0]) ) ;
使用的信号包括:数据信号data_a, dat_b;读写有效信号wren_a, wren_b;地址信号address_a, address_b;时钟信号clock_a,clock_b;输出数据信号q_a,q_b。可以看到所有的信号都是成对出现的,就是为了进行乒乓方式的数据传输。分成了两个RAM区域,A 和B,相当于前面讲乒乓方式里的数据缓冲模块1 和2。两个RAM 块是交替着读写(由I_a和I_b决定),输出数据流也是由I 决定。刚说到写时钟是13.5M,读时钟是27M,所以clock_a 和clock_b必须是读写时钟切换着输入,而且地址的计数也不一样,写周期时候地址增加的时钟是13.5M,读周期地址增加的时钟是27M。所以每行的数据读了两遍,相当于隔行变逐行。图6是在Quartus II下RAM的乒乓操作功能仿真图:
图6 RAM的乒乓操作仿真图 {{分页}}
RAM块进行乒乓方式操作信号的分配表如下: