又到了一年一度的招聘季节,有粉丝私信问了一个问题,一个关于以前流传出来的大厂面试的题目,个人觉得算是比较经典的题目,也是工作中经常遇到的一个问题,所以准备写一篇回答下。
有一个数据需要从A时钟域同步到B时钟域,数据位宽是512bit的,但是考虑到其他原因,目前只允许使用256bit异步FIFO(已经考虑空度满写的保护),因此设计了一个方案,如下图所示,请问该方案有什么问题?如何优化?
通过上图我们可以看到,512bit的数据,被分成了2组256bit的数据,采用同一个写使能信号写入到2个不同的异步FIFO中。在读这一侧,通过一个FIFO的空信号,同时将2个FIFO中的数据读出来。乍一看起来好像没有什么问题,且仿真的话,也不会有问题。但是在实际芯片中却不是这么回事。主要的错误就是误认为完全相同的异步FIFO在空、满信号状态上表现也一样。
我们知道异步FIFO的空满信号是通过格雷码地址经过转换后比较得到的,而格雷码在穿越异步时钟域的时候,由于亚稳态,有可能造成穿越的结果出现延迟。如下图所示,在t1时刻,写地址的格雷码已经由00变成01,即写入了一个数据。读时钟r_clk在采样的过程中,由于亚稳态写地址同步后,可能得到01,或者00,如果得到01,那么在t2时刻empty信号就可以拉低了,如果是00,那么在t2时刻empty不会拉低,需要在t3时刻拉低。
一句话总结,对于2个完全一样的异步FIFO,即使同时写入数据,在读时钟域,empty信号的产生也是不一样的,同样,在写时钟域,full信号的产生也是不一样的。
这个问题的解决方案其实很简单,写入测,ready_o信号的产生不能只使用fifo_1的满信号,也要使用fifo_2的满信号,即ready_o = full1_n & full2_n(full低电平有效)。同理,在读数据的时候,不能只看fifo_1是否空,必须是2个fifo都不空的时候才可能读数据。
其实上面这个题目在实际项目是经常用到的。2个FIFO被同时写入的时候,默认为2个FIFO是同时不空的,通过上面的分析,我们知道异步FIFO不是这么回事,那同步FIFO呢?理论上来讲,同步FIFO是同时不空的。但是不同厂家设计的FIFO,其特性可能也有差异,从代码的可移植性和可靠性来讲,也不建议采用一个FIFO为空就推断另一个FIFO也为空的方案,必须严格遵守:使用哪个FIFO,就要使用它的空、满信号。
全部0条评论
快来发表一下你的评论吧 !