• 异步FIFO设计的仿真与综合技术(4)


    概述

            本文主体翻译自C. E. Cummings and S. Design, “Simulation and Synthesis Techniques for Asynchronous FIFO Design 一文,添加了笔者的个人理解与注释,文中蓝色部分为笔者注或意译。前文链接:

    异步FIFO设计的仿真与综合技术(3)icon-default.png?t=N7T8https://blog.csdn.net/apple_53311083/article/details/132859029?spm=1001.2014.3001.5502

    FIFO style #1 

            FIFO样式#1的框图如图5所示:

            为了便于对风格#1的FIFO设计进行静态时序分析,该设计被划分为以下6个Verilog模块,具有以下功能和时钟域(这部分我们只是进行一个简单的介绍,具体的实现方式将在文章的后面部分带来):

    1、fifo1.v

            (参见第6.1节中的示例2)-这是包含所有时钟域的顶层封装模块。顶层模块仅用作一个封装来例化在设计中使用的所有其他FIFO模块。如果将这个FIFO用作更大的ASIC或FPGA设计的一部分,那么这个顶层封装模块可能会被丢弃,以允许将其他FIFO模块分组到它们各自的时钟域中,以改进综合和静态时序分析。

    2、fifomem.v

            (参见第6.2节中的示例3)-这是由写和读时钟域同时访问的FIFO内存缓冲区。这个缓冲区很可能是一个实例化的同步双端口RAM。其他内存样式可以适应作为FIFO缓冲区。

    3、sync_r2w.v

            (参见第6.3节中的示例4)-这是一个同步器模块,用于将读指针同步到写时钟域。同步读指针将被wptr_full模块用来生成FIFO满条件。此模块只包含与写时钟同步的触发器。此模块中不包含任何其他逻辑。

    4、sync_w2r.v

            (参见第6.4节中的示例5)-这是一个同步器模块,用于将写指针同步到读时钟域。rptr_empty模块将使用同步的写指针来生成FIFO为空的条件。此模块只包含与读时钟同步的触发器。此模块中不包含任何其他逻辑。

    5、rptr_empty.v

            (参见第6.5节中的示例6)-此模块与读时钟域完全同步,并包含FIFO读指针和空标志逻辑。 

    6、wptr_full.v

            (参见第6.6节中的示例7)-此模块与写时钟域完全同步,并包含FIFO写指针和满标志逻辑。

            为了使用这种FIFO设计方式能够执行FIFO full和FIFO empty测试,必须将读写指针传递到相反的时钟域以进行指针比较。与其他FIFO设计一样,由于这两个指针是由两个不同的时钟域生成的,因此这些指针需要“安全地”传递到相反的时钟域。本文所展示的技术是同步格雷码指针,以确保一次只有一个位可以改变。

    为什么要用格雷码

            以下的所有部分非原文内容,为笔者自行补充。

            在本文中使用到了格雷码指针,实际上在如今大量的异步FIFO的设计中,都会使用格雷码来替代二进制码来实现FIFO的指针,但是具体的原因在原论文中没有详细展开,只是简单提到了确保只有一个指针位被改变,这里我们进行一个简单的说明,为什么异步FIFO的设计一般会采用格雷码的形式来实现指针。

            我们知道了判断FIFO的空、满需要将读写指针分别同步,而跨时钟域传输的一旦没处理好就会引起亚稳态问题,造成指针的值异常,从而引发FIFO的功能错误。那么应该如何将读写指针同步到对方的时钟域呢?

    1、避免使用二进制指针

            由于两个指针所处的时钟域不同,且彼此异步,在使用二进制计数器实现指针的时候,就会导致用于比较的指针值取样错误,例如:二进制指针FFF->000。这时所有的位都会同时发生改变,虽然能够通过同步计数器避免亚稳态,但是仍然可能得到极其不相关的取样值,所以同步计数器不是最终的解决方案。

            从FFF->000的可能情况有:

    • FFF->000
    • FFF->001
    • FFF->010
    • FFF->011
    • FFF->100
    • FFF->101
    • FFF->110
    • FFF->111

            如果同步时钟沿在FFF->000的中间到来,就可能将3位二进制数的任何值取样并同步到对侧时钟域,这就会使得FIFO同步后的读/写指针错误,从而导致FIFO的空/满信号错误,最终导致FIFO运行异常。

    2、使用格雷码代替二进制实现指针

            实现FIFO指针的一种方式是使用格雷码,如下图所示:

            格雷码的一大优势是在从一个数变化到相邻的另一个数的时候,只有一个位发生变化,也就是一种单位间距码,因此,在发生转换时,最多出现一位的错误,例如,计数器从“1010”变化到 "1011"  ,取样值只可能是“1010”或者“1011”。即便没有采集到变化后的1011,也会采集到变化之前的1010,这就避免了由于采样指针错误导致的空/满信号错误的可能性。

  • 相关阅读:
    【.Net实用方法总结】 整理并总结System.IO中DirectoryInfo类及其方法介绍
    Javascript知识【jQuery-validation插件】
    Huawei_Netconf_Ncclient
    《Python+Kivy(App开发)从入门到实践》自学笔记:第六章 打包——知识点总览
    【ubuntu noble】docker 容器无法使用 nvidia gpu
    Spring Boot 如何进行多环境配置
    linux删除修改时间之后的文件
    chromium114添加新的语言国际化支持
    Set 与 Map 的使用
    小孩近视用白炽灯好吗?使用护眼台灯有啥好处?
  • 原文地址:https://blog.csdn.net/apple_53311083/article/details/132899707