FPGA:跨时钟域数据交互
0赞为了实现OV7725视频采集,同时实时显示于VGA显示器,我们需要将捕获后的数据交给VGA进行实时显示,但我们却不能简单的实现这一功能~~~~(>_<)~~~~,太多人问过我这个问题,今天在这里总结一下!!!
这并非OV7725输入的视频流数据量有多大,也不是因为输入视频数据不连续,而是因为时钟的不同步,造成我们不能直接进行数据的交互。因此我们直接解决了这一个问题,才能完成不同时钟域的数据交互,以保证数据流的连续性,完成实时VGA视频显示的功能。分析OV7725视频采集到显示之间的时钟域,主要有以下几个方面(这里只考虑RGB565/YUV422格式,RAW直接输出12.5MHz):
① 在RGB565/YUV422下,OV7725在25MHz的时钟驱动下,以25MHz的数据时钟的速率,输出8Bit的数据流。
② OV7725输出视频流经FPGA捕获、解码后,以12.5MHz的速率输出拼接后的16Bit像素数据,并且每秒30帧。
③ 针对640*480分辨率,VGA格式为640*480@60Hz,此时VGA的驱动时钟为25MHz(OV7725像素时钟的2倍),帧率为60(与OV7725输出帧率不一致)。
这样,在整个系统的框架中,我们得到了3个时钟域,如下图所示:
3个时钟域的数据交互,涉及到了2次跨时钟域的过程。首先在采集时从25MHz过渡到12.5MHz,在这需要从12.5MHz提升到25MHz给VGA显示。如果我们不经过处理,直接在时钟2驱动下读取时钟1输出的数据,直接跨越了时钟,是否可行?
由于跨时钟域数据的操作,当输入信号从时钟域1跨入时钟域2时,对于时钟域2而言,该数据是一个异步信号。而异步信号造成的亚稳态不稳定性,Bingo过去的文章种豆提到过,这一潜在的危机,也许会造成致命的伤害。为了避免这种情况的发生,实现数据从一个时钟域过渡到另一个时钟域,我们需要需要采用一定的办法,来解决跨时钟数据交互问题。
广义的跨时钟域,不仅仅局限于时钟频率的不同,始终相位的不同也可以认为是跨时钟,典型的2个处理器即便主频一样,也认为为跨时钟域,因为两者相位不可能一样。为了解决跨时钟数据交互,Bingo认为,主要有以下3种方法:
① 采用使能信号实现跨时钟域数据交互
这一方式我们在前面已经多次应用。比如在FPGA与MCU进行SPI总线通信时,FPGA捕获外部输入的SPI_CLK信号,通过边沿采样原理,得到SPI_CLK的上升沿使能时钟(mcu_en)。继而进行使能的判断,读取外部输入的数据,实现跨时钟域数据的交互,框图如下所示:
通过FPGA边沿采样原理,捕获使能时钟来解决跨时钟域数据交互,在FPGA设计中非常的常用。采用使能时钟进行跨时钟域数据交互,实现方式非常的简单,也非常适用于FPGA实现。不过这种方法也有一定的局限性,由于高频时钟能采样到高频时钟,而高频时钟不能采样到低频时钟,因此这决定了数据流只能由低频域向高频域传输时。比如在SPI总线通信中,MCU的时钟相对于FPGA而言,属于低频域。
当外部时钟与FPGA主时钟旗鼓相当时,采用这种方式进行跨时钟与数据交互就会有很大的问题。比如当年Bingo在进行CPLD与STM32的FSMC总线通信时,在FSMC以较低时钟运行时,数据交互完全没有问题;而在设定FSMC以最高速率运行,数据的丢失就很严重。最后用逻辑分析仪观察STM32输入的信号,如下图所示:
同时查阅手册,发现了问题的所在。由于STM32的FSMC以硬件电路运行,能达到很高的速率(实际测试能达到每秒10张以上的1024*768的模拟图片),而在最高速率下,STM32的FSMC总线的WR信号,将在72MHz的主频下运行。问题在于项目中CPLD主时钟为50MHz,因此使用50MHz去采样72MHz的时钟域数据,不出问题才怪……最后,通过更换100MHz的晶振,解决了WR的是能采样问题。
② 采用片内存储器实现跨时钟域数据交互
这个方法主要是利用存储器的双端口读取,由于FPGA片内RAM、FIFO等,都可以设置成双端口读取模式,即独立的读时钟与写时钟。由于双端口 RAM、DCFIFO等读写操作,其固有特性决定了可以在2个时钟域下进行数据的读写操作。双端口RAM与DCFIFO的Module如下图所示:
在跨时钟域读写操作中,将输入连接到时钟域1,将输出连接到时钟域2,通过地址,或者判断存储器内存储的数据,确定数据达到了饱和,开始进行数据的交互。
由于DCFIFO采用的是先入先出机制,同时根据存储的容量判断所存储的跨时钟域数据的量,很容易的就能实现跨时钟与数据的数据交互。个人觉得采用DCFIFO实现跨时钟与数据的交互更容易,更适合。在SDRAM控制器中Bingo就采用了2个DCFIFO实现跨时钟域数据的交互。
采用DCFIFO实现跨时钟域的数据交互的好处在于,能实现低频域到高频域的数据交互,同时由于FIFO有一定的存储量,也可以实现由高频率到低频域的数据交互。在实际项目开发的跨时钟域数据交互中,采用DCFIFO作为交互的中介,非常的使用。
③ 采用SRAM/SDRAM等存储器作为跨时钟域数据交互
由于片内存储器有限,当数据量较大时,采用外部存储器,也能实现跨时钟与数据交互。这里的SRAM/SDRAM相当于双端口RAM。最简单的方式,可以采用2片SRAM/SDRAM,模拟实现双端口RAM,实现循环“时钟域1写、时钟域2读”的乒乓读写机制,框图如下所示:
从乒乓读写操作框图中分析,这种方式实现的跨时域数据交互主要是如下3个过程:
① 在第一时刻,外部数据通过时钟域1写入SRAM1/SDRAM1,同时通过时钟域2读取SRAM2/SDRAM2数据;
② 在第二时刻,外部数据通过时钟域2写入SRAM2/SDRAM2,同时通过时钟域2读取SRAM1/SDRAM1数据。
③ 当SRAM1/SDRAM1写入完毕,并且SRAM2/SDRAM2读取完毕,切换一次乒乓操作。这需要处理SRAM1/SDRAM1写入完毕,而SRAM2/SDRAM2未读写完毕的数据。
以SRAM/SDRAM来实现跨时钟域数据交互,好处在于实现海量跨时钟与数据的处理,能同时实现低频域到高频域,或者高频域到低频与的跨时钟数据转换。另外,SRAM的驱动时序简单,便于实现,但是价格高;而SDRAM的驱动时序复杂,实现困难,但是价格便宜。在实际项目开发中,根据周期与产品的成本敏感程度而定。
上述三种跨时钟域数据交互的方法,在OV7725视频采集显示的设计中,每一种都淋漓尽致的应用到了。处理好跨时钟域数据的交互,有效地提高系统的稳定性,防止数据的错位与丢失,在开发中极为重要。最后,给出Bingo设计的OV7725视频采集系统中,3个跨时钟域数据处理的框图,如下所示: