在数字电路设计里,只要涉及两个不同时钟域的数据交互,异步FIFO基本是绕不开的。比如ADC采样时钟跟FPGA主控时钟不一样,或者两个芯片之间用不同的时钟通信,这时候直接把数据从一个时钟域送到另一个时钟域,十有八九会出问题。异步FIFO就是专门解决这个问题的。
先说说为什么直接跨时钟域不行。数字电路里的触发器有建立时间和保持时间的要求,如果数据在时钟沿附近变化,触发器采样时可能进入亚稳态,输出既不是0也不是1,传播下去就会导致系统错误。异步FIFO通过在两个时钟域之间加一个缓冲区,让数据先存起来,再由接收侧的时钟读出去,这样就避免了直接的时钟域跨越。
异步FIFO的核心结构是一个双端口RAM加上读写指针控制。写端用写时钟把数据写进RAM,读端用读时钟把数据读出来。关键是要判断FIFO的满和空状态——写满了不能再写,读空了不能再读。满空判断需要比较读写指针,但读写指针在不同的时钟域,直接比较会有亚稳态问题。
这里就用到了Gray码(格雷码)。Gray码的特点是相邻两个数之间只有一位发生变化,比如000→001→011→010→110。把读写指针转换成Gray码再跨时钟域同步,即使同步过程中出错,最多也只会差一个位置,不会出现指针乱跳的情况。具体做法是把写指针的Gray码同步到读时钟域来判断空,把读指针的Gray码同步到写时钟域来判断满。
同步的时候一般用两级触发器来打拍,降低亚稳态传播的概率。第一级触发器采样可能进入亚稳态,但经过一个时钟周期后大概率会稳定到0或1,第二级再采一次,基本就能得到稳定的信号。虽然理论上亚稳态不能完全消除,但两级同步已经能把出错概率降到非常低的水平。
设计异步FIFO还有几个细节要注意。第一是深度选择,要根据读写速率差和突发长度来定,太深浪费资源,太浅容易溢出。第二是满空判断的边界条件,设计时要确保不会出现同时满和空的情况,一般用指针的最高位和次高位来区分。第三是复位设计,异步复位要注意释放同步,否则读写指针可能在不同时钟域下复位不一致。第四是验证,跨时钟域的验证不能只看功能仿真,还要做门级仿真和时序分析,确保没有亚稳态风险。
上一篇:国内首款AI辅助创新药获批上市
下一篇:没有了