FIFO写数据失败问题分析

描述

以下文章来源于西风念,作者zwliu

前几天测试中心在对伺服电机控制板进行测试中,发现多次随机点击控制屏上控制指令时,会出现正常运行的电机突然就停了。在当前指令还没有执行完,并且确认没有下发急停指令的情况下,正常转着的电机突然就停了。

突然停机,,马上要交付的机器突然暴露还有问题,慌得一批。明明之前都经过长时间测试了的,不管了,赶紧查原因。

复位信号

1、首先查复位信号,对系统发起复位重启指令,能恢复,所以我一开始还以为是不是系统误发了复位指令,于是继续测试,让现象复现,此时去查看复位信号寄存器,显示复位信号是正常的;

2、该板子由于没有引出jtag无法使用在线逻辑分析仪VLA看信号,当时为了方便排查设计问题,将很多关键信号引入到了寄存器,通过寄存器一路排查,发现问题出在fifo上。Fifo数据写不进,前方发来的控制指令无法被后方的执行端正确接收,也就是说控制指令传达不下去,信号在这里中断了。

下图:fifo接收上位机过来的指令,指令数据缓存在同步fifo,下级模块在fifo读取相应的指令做执行。

复位信号

2、因为设计中对写使能信号,写数据,以及fifo数据量都做了监测,写使能是单周期脉冲信号,通过计数器对写次数,以及写数据都进行了累加,这些统计信号都放到了寄存器,于是直接把寄存器状态值调出来看,发现写次数一直在累加,写数据也在变化,但是数据量却一直保持为0,也就是这个FIFO在写时钟正常,写数据正常的情况下,数据却死活写不进,读不出数据,数据量保持为0不增加。

这种情况一开始确实一点违背我的认知逻辑了,我认为在写信号正常的情况下,并且fifo数据量为0也就是fifo为空的情况下,写不进数据,这很难理解。

于是去网上搜索,看看有没有人出现过类似的现象,一搜还真有好几篇文章提到这个问题,都说在工程中遇到了FIFO写不进的问题,并且解决问题的过程费了很大的功夫,花了很长时间才定位到问题所在,比较典型的是明德扬写的这篇:

截图如下:

限于篇幅,只截了一部分,如果有遇到了类似的问题可以搜索这篇文章看全篇,他们最后是查阅官方FIFO手册,提示fifo的复位信号必须是和写时钟同步,也就是异步复位存在亚稳态,会导致低概率的错误使FIFO无法工作,就是说不能使用异步复位。

于是把异步复位同步化,问题得到解决。

问题是他们的测试过程都是反复开机,这种情况可能发生在上电的时候,一上电由于复位信号异常没有正确复位,是有可能导致系统不能正常工作。

可是我这里的情景并不相同,不是上电之初,而是工作中突然死机,感觉和复位信号关系不太大,但是我又没有好的办法,还是按同样的方法对复位信号同步处理。测试结果还是会死机,也就是说确实和这个复位信号无关。

这下有点一筹莫展了。。。

思考良久,我在想是不是vivado的IP核还有哪里有需要注意又没有注意到的方,但是黑盒子我又没办法查细节原因。于是索性不用官方提供的fifo,自己动手写了个同步fifo,自己写的fifo当然所有的细节原理自己是很清楚的,即使出现问题,也是很容易查的。

结果是把自己写的同步fifo挂上去,电机还是照死不误,只是这样一来,我就清楚了应该不是fifo的用法问题了,应该是设计逻辑哪里还有隐藏的问题;

fifo是做过基础的仿真的,逻辑是没有大问题的。开始把写的fifo拿出来仿照实际工作环境进行更细致地仿真,我们的使用条件是,上位机每隔一段时间发一次数据,比如10毫秒,FPGA把时间起点错开,然后在FIFO后端逻辑每隔10毫秒取一次数据,并且这个间隔时间是相对很稳定的。上位机和FPGA都做了严格的控制,确保5毫秒的精确度,上位机的5毫秒精度可能因为系统原因不能很准确,允许左右偏移1-8ms都可以,但是不能出现累计误差。

Fifo的读机制是自动根据数据量判断非空,非空就立即启动读动作。

现在仿照实际环境进行测试,固定间隔写,等间隔固定读,可以看到同时开启读写,数据量是保持0,1平衡的;

复位信号

本来想错开一点,提前写入两个数据,让fifo数据量保持在2,3之间,结果手误写使能没有拉低,一直在写数据,直接把fifo干满了。这下看到的情景令所有问题豁然开朗。

复位信号

1、fifo满了以后的数据个数不是最大值,而是溢出清零后变成最小值0;

2、之前以为fifo数据量等于0就以为fifo是空的,这里却恰恰相反,fifo数据量为0的时候可能是fifo刚满溢出了导致清零。

3、写满导致fifo一直写不进数据,数据量保持为0;

4、数据量为0,导致系统认为fifo一直是空状态,无法自动发起读信号;

5、这次上位机控时测试机制有点问题,导致写快于读,原以为不会出现写满的情景,如果操作不当还是会出现写满,写满就会卡死停机。

于是很快确定原因,当前测试的上位机时间控制设置不够严谨,导致双方同步时间产生累计误差,这个误差累计长了就会把fifo填满,而我们的设计本意是得有机制保证不会出现写满才行。这个后面把fifo深度加大,长时间测试后出现数据滞后的原因是一致的。

下面在vivado用官方的IP复现这一现象:

复位信号

复位信号

fifo深度设置为16,连续写,发现数据写入16个数后,full信号拉高,此时数据量并不是保持在f,而是会在此刻清零。最开始以为的数据量是0,做出fifo是空的判断是错误的。

复位信号

Fifo的用法是芯片/FPGA设计的基础,早些年也写过一系列的测试笔记只为全方位理解fifo的工作逻辑和用法,包括:

1、standard fifo模式和first fall-through模式的区别

2、fifo复位的机制,复位时间复位时长

3、读写信号自动关联empty和full的关系

4、wr_rst_busy信号的使用逻辑

5、fifo用来打包传输控制信号和数据信号的方法

6、同步异步fifo数据量和Fifo模式以及读写信号之间的对齐关系

等等...

这些机制对于正确设计fifo逻辑,对于系统稳定性都很重要,今天也算是发现一个以过去的经验可能会忽略导致出错的地方,觉得还有点意思,于是整理分享出来。

很多时候我们的知识的获取来源于网络,来源于众多网友的经验总结,时常怀着一颗感恩的心,也想着回馈于网络,于是也会分享一些小经验,若能使人有益,也觉得挺有意思。

另外也是自己的一种学习手段,凡是问题,总是觉得凡是问题,能清晰地表达和总结出来就是真的理解了。

保持输出就是持续学习的动力。

所以经常和身边的家长或小朋友说学习也是这样的,只有用输出倒逼输入,二者构成反馈闭环,学习才是有效的,才会学以致用正向促进。通过不断地输出和反思,我们可以不断完善自己的知识结构。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分