格雷码的事聊完了,后面顺理成章的就是读写通路模块的设计。不过在读写控制通路之前还要明确下另一个问题,就是空满信号的产生位置的事情。
这个问题在面试时的问法是:空满信号分别在哪个时钟域产生?
众所周知,信号跳变时打两拍(或者三拍)能够消除亚稳态,但是信号从亚稳态恢复的时候不一定恢复成0还是1。而因为格雷码每次变化1比特的特性,可以保证即使恢复错了也不过是错成之前的值罢了。
当然了即使没有亚稳态误恢复的问题,读写指针传到对面的时钟域去,总归会延迟好几拍的,所以在写时钟域看到的读指针是落后于实时读指针的,同理读时钟域看到的写指针也是落后于真实的写指针的。
那么来分析下滞后的影响,令fifo_cnt为fifo中已有的数据量计数值。
1.waddr准确,raddr滞后,那么计算得到fifo_cnt会偏大。如waddr=7,raddr=4,滞后的raddr=1,计算得到fifo_cnt为6,而实际上fifo_cnt为3;
2.waddr滞后,raddr准确,那么计算得到fifo_cnt会偏小。如waddr=7,raddr=4,滞后的waddr=5,计算得到fifo_cnt为1,而实际上fifo_cnt为3;
进一步的,如果fifo_cnt计算偏大了,对于读和写来说会有什么影响呢?读可能发生功能问题,写可能发生性能问题。读可能发生功能问题在于,本来你里面没数了,结果fifo_cnt算的偏大还以为有数,有数就能读一读就出错了。写可能发生性能问题在于,本来你里面没满呢,结果fifo_cnt算的偏大还以为满了,满了就不能写本来能写的写不进去那性能不就降下来了么。
如果fifo_cnt计算偏小了,对于读和写来说会有什么影响呢?读可能发生性能问题,写可能发生功能问题。读可能发生性能问题在于,本来你里面还有数,结果fifo_cnt算的偏小还以为没数了,没数了就不能读了。写可能发生功能问题在于,本来你已经满了,结果fifo_cnt算的偏小还以为没满,没满就能写一写就出错了。
所以,对于写fifo而言,fifo_cnt计算偏小不可接收,fifo_cnt计算偏大可以接收,所以满信号必须由准确的waddr和滞后的raddr产生,也就是在写时钟域产生。
对于读fifo而言,fifo_cnt计算偏小可以接收,fifo_cnt计算偏大不可接收。所以空信号必须由滞后的waddr和准确的raddr产生,也就是在读时钟域产生。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !