异步FIFO_异步fifo读写时钟频率限制-程序员宅基地

技术标签: verilog  

注:代码链接在文末,有需要直接移至文末观看。
注:更多精彩请看:面试常问的verilog代码汇总 一文


简介

异步FIFO 的读写是用不同的时钟来控制的,所以不能采用共享同一个计数器的方法来产生空满标志。那么我将通过引入问题的方式,逐步异步FIFO中重要的概念和机制,再来进行代码环节。

注:同步FIFO也可以看同步FIFO

指针该怎么设计?

将读写指针向高位扩展一位,也就是说,深度为2n 的异步FIFO,读写指针的宽度应该为(n+1)位。当读写指针指向最FIFO中的最后一位时,指针最高为从0变为1,其他位变成0,指针再次折回到FIFO的首位。
在这里插入图片描述

空满标志产生的条件?

因为读写指针向高位扩展一位,所以当使用二进制进行编码读写指针时,空满标志为:

  • 读写指针相同时,FIFO为空。只有在复位操作或者当读指针读出FIFO中的最后一个数据时,读指针追赶上了写指针。
  • 读写指针最高位(MSB)不同,其他位相同时,FIFO为满。这说明写指针比读指针已经多折回了一次,此时FIFO已满。

为什么是格雷码?

用上面二进制编码读写指针,这样问题就真的解决了吗?还是那个问题,读写指针是在不同的时钟域,要进行跨时钟域同步(不太了解的可以看跨时钟域传输),这势必要考虑传输时的亚稳态问题。采用二进制码进行读写指针的编码时,我们知道,其相邻点的递增可能有好几个二进制位同时发生变化。而在异步FIFO中,我们一般采用两级触发器同步打两拍的方式进行读写指针的同步。也就是说,如果使用二进制进行编码,就不能采用这种简单的同步两拍的方式,因为这种方式只能进行单bit信号跨时钟域传输。那为何解决这个问题?
采用格雷码。格雷码是一种在0 ~ 2n -1之间循环变化的编码,其相邻两个数值之间只有一位二进制位发生变化,有效的降低了在指针同步的过程中产生亚稳态的概率。
所以采用格雷码后,产生空满标志的条件又要变一变了。

  • 空标志:读写指针所有位均相同
  • 满标志:读写指针最高位(MSB)不同次高位不同其他位相同

PS:这里我补充解释几个点:

1.为什么要改变满标志判断条件?

答:假如是如下图所示的4位格雷码,FIFO深度为8,读写指针从0000 ,…,0100(7)再到1100(8)。格雷码具有镜像对称的特点,这里的1100(8)的意义就相当于指针折回到FIFO的首位(0000)。所以假如此时要比较满时,要比较1100和0000,也就是要满足最高位和次高位不同,其他位相同。在这里插入图片描述

2.是用格雷码需要注意什么?

答:格雷码只有满足2n 个数,才可以形成循环,否则会导致相邻位不止一位发生变化。这也就是使用格雷码作为读写指针时,FIFO的深度必须为2n 。有的时候宁愿浪费一点空间,也要将深度设为2n
例如:如果设置FIFO的深度为6,首位跳变时有多位发送变化。
在这里插入图片描述

3.格雷码同步时出错了,怎么办?

答:格雷码每次只要1位二进制位发生变化,这样在进行地址同步时,如果地址同步出错,如下图:写地址跳变由000到001,同步时出错,将写指针由001同步成000。

在这里插入图片描述
尽管写地址跳变出错,在读时钟域判断空是否产生空标志时也不会出现严重错误,最坏的情况就是让空标志在FIFO不是为空的时钟产生空标志,也就是假空的情况。但是不会产生更加严重的空度情况。

4.格雷码与二进制之间的转换?

答:这个还是看我之前的博客:IC验证面试题(题2),描述的更详细。

空满标志产生需要读写指针如何同步?

首先我们要明白,读写指针受不同的时钟控制,假如你把写指针同步到读指针时钟域中去判断满,行不行?不行,假如加入此时你判断了为满(最高位和次高位不同,其他位相同),控制FIFO不要再写了。但你注意了,此时写指针在经过两级触发器同步到读时钟域的过程中,写指针它在写时钟域中还进行了至少两次的写操作(一般写时钟更快),这就造成了FIFO的溢出。
那么该怎么办?

  • 满标志: 将读指针同步到写时钟域,告诉写信号“你TM别写了!,再写就溢了”
  • 空标志:将写指针同步到读时钟域,告诉写信号“你TM别读了!,再读就空了”

那么这就有个问题了?上面说同步的过程中,FIFO实际还在写,所以会造成写满。那你现在把读指针同步到写时钟域来判断满,实际FIFO应该还未满,这不造成羞耻的浪费了嘛。其实这种设计称为保守设计,就是为了增加FIFO的安全性,防止写指针孬头吧唧地写满了。同理,也防止读指针孬头吧唧地产生空读,读出无效数据。

FIFO的深度如何计算?

Question1:写时钟频率为100MHz,读时钟频率为80MHz。每100个时钟周期写入80个数据,每一个周期读出一个数据。那么FIFO的深度应该是多少?
首先我们要确定最极端的情况,也就是FIFO的Burst 会写了多少个数据。这里要考虑数据是“背靠背”传输的,如下:
在这里插入图片描述
这种情况是,前100个时钟周期,数据在后80个周期内发生了连续的写操作,在后100个时钟周期内,数据在前80个周期写入。这就造成了:

  • 数据突发长度为 :160
  • burst长度(160个数据)写入需要的时间:burst长度/写时钟频率 = 160/100
  • burst长度(160个数据)写入期间可以读出的数据量:160/100 ÷ 1/80 =128
  • FIFO的深度:160 - 128 = 32

Question2:设计一个同步FIFO,每100个时钟周期可以写80个数据,每10个周期可以读8个数据,FIFO的深度为多少?
和上面的情况一样,burst长度为160。所以:

  • burst长度(B)为:B =160
  • 写入B长度所需的时间:T = (1/fwr)*160
  • 从FIFO中读出一个数据所需的时间:t = (1/frd)*(8/10)
  • 在T时间读走的数据量:T/T= 160* (frd/fwr)(8/10)
  • FIFO的深度:160 - 160* (frd/fwr)(8/10)

因为是同步FIFO,所以frd/fwr = 1,代入得 深度为32。
由此我们可以推出FIFO的计算公式:
在这里插入图片描述

想了解FIFO深度的计算场景,还可以看一个大佬的FIFO深度计算

FIFO的测试点?

question1:(22届乐鑫提前批)一个异步FIFO,rdata和wdata均为8位,FIFO深度为16,当rst_n为低时,FIFO复位。当wclk的上升沿采样且wr为高时,数据被写入FIFO,当rclk的上升沿采样且rd为高时,FIFO输出数据。此外,当FIFO为空时,EMPTY为高,当FIFO为满时,FULL信号为高。尽可能列出你能想到的FIFO测试点。

有两个一级测试点:1.FIFO的基本功能;2.异步处理

1.FIFO的基本功能测试包括:

  • 检查端口时序。

    1.检查数据数据是否在wclk的上升沿并且wr为高时被写入。如,在wr为高或为低时写入的数据能不能被有效写入。

    2.检查数据数据是否在rclk的上升沿采样且rd为高时读出。

  • 数据一致性。先写后读,检查是否能按先入先出的顺序读出;

  • 空满信号能不能正确生成。先连续地写,再连续的读,检查空满信号是否准确生成;

  • 读写指针有没有做空满限制。当FIFO满时,外部有没有做保证写指针不会增加;当FIFO空时,读指针是否还在增加;

  • 检查复位信号,各个寄存器和信号是否能被正常复位,复位释放后信号的初始值是否正常;

  • 读写指针转换为格雷码的逻辑检查。

2.异步处理:

  • 读写指针跨时钟域传输时,有没有做同步处理。
  • FIFO的读写时钟频率差速耐受能力。检查读快写慢、写慢读快一定周期后,FIFO是否还能保持稳定。

异步FIFO的verilog代码

异步FIFO的结构如图所示。由读时钟域、写时钟域、Mermory模块和跨时钟域同步组成。
在这里插入图片描述

异步FIFO代码

本博客内容过长,不方便阅读。详细代码请看我的另一篇博客:异步FIFO代码(Verilog)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/SummerXRT/article/details/117814863

智能推荐

c++求矩阵的秩_对于向量和矩阵的理解-程序员宅基地

文章浏览阅读316次。学数值计算还有复变函数了喔,矩阵忘干净了。又看了一遍 蓝棕 的相关的讲解,总结一下。1.向量是什么?从初到末的箭头(物理角度,表示一种运动过程)有序的数字列表(计算机/数学角度)[1,2]加和数乘运算有意义的anything(抽象意义)12两种理解之间的关系就是线性代数的奥秘,即几何角度与数值角度。一个向量的坐标由一对数构成,可以理解为从原点到终点的箭头,描述运动过程。比如,规定好坐标平面的单位,..._求矩阵的秩c++

从事汽车电子软件开发需要什么技能?_汽车mcu开发怎么入门-程序员宅基地

文章浏览阅读6.6k次,点赞8次,收藏90次。​前不久有一个朋友想转去做汽车软件开发,问我需要学习什么内容。今天在这里做一个分享,希望可以帮到这位朋友以及以后想要从事汽车电子软件开发的朋友们。随着SDV(软件定义汽车)概念的提出, 大家都认识到了软件在汽车电子领域的重要性,各大汽车主机厂纷纷成立了软件研发中心并争夺软件开发人才。上汽集团在今年年初成立了上汽软件中心(后改名为零束),长城汽车成立了诺博、诺创、诺博,还有很多OEM也成立或者扩大了各自的软件研发中心,这里都不赘述了。总之,这对从事汽车软件开发的同僚们是很大的利好。2019年大家经历了汽车_汽车mcu开发怎么入门

数学建模灵敏性分析(一阶、二阶灵敏度)python代码+懒人专用版_计算一阶sobol敏感性指数 python-程序员宅基地

文章浏览阅读9.2k次,点赞21次,收藏207次。对于勉强看懂了灵敏度分析的同学来说,本文给出一个方便移植、修改的python程序,可以很方便地进行灵敏度分析。_计算一阶sobol敏感性指数 python

怎样HTML做图片画廊,42个jQuery图片画廊插件-程序员宅基地

文章浏览阅读732次。这里列出了使用jQuery构建的42个jQuery图像库、滑块、插件和教程:1. TN3 GalleryTN3 Gallery是一个完整的基于HTML的可定制的图像库,包含幻灯片、转换和多个相册选项。兼容所有现代桌面和移动浏览器。由jQuery提供。2. AD Gallery当我编写可编辑的选择插件时,我受到了自己的启发,所以我决定再写一个。这是一个与插件类似的图片库插件,比如Thickbox和L..._jthumb

flink 流式处理中如何集成mybatis框架_flink集成mybatis-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏6次。flink 中自身虽然实现了大量的connectors,如下图所示,也实现了jdbc的connector,可以通过jdbc 去操作数据库,但是flink-jdbc包中对数据库的操作是以ROW来操作并且对数据库事务的控制比较死板,有时候操作关系型数据库我们会非常怀念在java web应用开发中的非常优秀的mybatis框架,那么其实flink中是可以自己集成mybatis进来的。 我们这里以flink 1.9版本为例来进行集成。如下图为flink内部自带的flink-jdbc:创建一个fli._flink集成mybatis

SQL语言的数据类型_sql数据类型-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏21次。MySQL中的数据类型有很多,主要分为三类:1.数值类型;TINYINT 1byte (-128,127) (0,255) 小整数值SMALLINT 2bytes (-32768,32767) (0,65535) 大整数值MEDIUMINT 3bytes (-8388608,8388607) (0,16777215) 大整数值INT/INTEGER 4bytes (-2147483648, 2147483647) (0,4294967295) 大整数值BIGINT _sql数据类型

随便推点

MPICH下载安装-程序员宅基地

文章浏览阅读8.1k次,点赞14次,收藏53次。项目场景:MPICH环境搭建和配置以下是我个人的搭建过程中遇到的一些问题,仅作参考问题1 :不知道如何下载,或是下载哪一个版本。 mpich下载,官网下载地址:https://www.mpich.org/downloads/下载的指导如下在http点击右键,其他窗口打开,下载链接就打开了,此时安装包就开始下载了,压缩包的格式为tar.gz将下下载压缩包放到合适的目录,然后按照下面的指令解压tar -xzvf mpich-3.4.2.tar.gz创建安装目录,_mpich下载

车载智能终端TBOX_tboxshang c行驶速度-程序员宅基地

文章浏览阅读637次。终端设备是基于GSM/WCDMA/TD-LTE通讯方式的GPS定位移动终端,车载设备具有强大的车辆监控管理、新能源CAN总线数据采集等功能,可以满足不同用户的需求,同时具备汽车行驶记录功能扩展应用。_tboxshang c行驶速度

nvme固态必须uefi启动吗_【Ubuntu】UEFI安装Windows 10和Ubuntu 18.04双系统(深度爬坑)...-程序员宅基地

文章浏览阅读1k次。前言必须先安装windows。如果先装Ubuntu再装Windows。安装Windows时会覆盖 EFI分区已有的引导,那么Ubuntu的引导就丢了。而先装Windows再装Ubuntu,Ubuntu会在EFI分区追加引导内容,Windows引导不会丢。中间很尴尬,把电脑装的连UEFI BIOS都进不了了,逼不得已直接抠了主板上的纽扣电池,复位了一下主板。我最开始尝试的是ubuntu 18.04,..._nvme0是什么启动项

python中pos函数用法_Python基础之函数用法实例详解-程序员宅基地

文章浏览阅读4k次。本文以实例形式较为详细的讲述了Python函数的用法,对于初学Python的朋友有不错的借鉴价值。分享给大家供大家参考之用。具体分析如下:通常来说,Python的函数是由一个新的语句编写,即def,def是可执行的语句--函数并不存在,直到Python运行了def后才存在。函数是通过赋值传递的,参数通过赋值传递给函数def语句将创建一个函数对象并将其赋值给一个变量名,def语句的一般格式如下:de..._python中pos函数用法

Symbol的使用方法_symbol方法-程序员宅基地

文章浏览阅读3.4k次。SymbolSymbol的描述和写法ES6新增的方法 Object.getSymbol的描述和写法Symbol 是ES6新引入的一种基本数据类型 表示的是独一无二的值 他是js里面第六种基本数据类型​ 基本数据类型 : string number boolean undefined null​ typeof 的返回值 string number boolean undefined object functionSymbol函数生成的数据 是独一无二的 即便参数一样 那么表示的值也不一_symbol方法

无法从jinja2 引入 evalcontextfilter, Markup, escape_from jinja2 import markup, escape-程序员宅基地

文章浏览阅读4.3k次,点赞6次,收藏10次。1、问题描述:使用airtest 进行UI自动化测试,将python3.6 升级到python3.9。各种包安装完成后,运行脚本,报错:ImportError: cannot import name evalcontextfilter, Markup, escape from ‘jinja2‘无法从jinja2引入 evalcontextfilter, Markup, escape。2、解决办法查看了之前python3.6时的jinja2版本为3.0.3;升级到python3.9后,jinja2版本_from jinja2 import markup, escape