这里记录一个实际的需要使用乒乓操作的例子:读sd卡数据的时,在spi的模式下。发送单数据块的读取命令,在回应之后会有

512字节的数据。使用乒乓操作,可以用两个八位的寄存器,就可以完成连续的512字节读入fifo。但是如果操作不好的话就会出现位置不对的情况。

上图是读入fifo的数据。

上图是实际的数据。(起始地址为1000h)00h 01h,就是位置不对的地方。

上述结果的代码:

assign fifo_data_in = (i == 10'd7) ? data_read_1 : data_read_2;

分析代码可知:00. 01是不要的数据,但是确写入了fifo中。应该说猜了很久,都不知道。这也是我的弱点所在,不能猜,而要实在的仿真分析。在我仿真了fifo的波形后,才知道fifo的写入当前时刻的,上一时刻的值见仿真波形。还有就是我的猜测:fifo写入的值,如果不使能write_req_r信号,值就不会更新到实际的fifo的数据总线上。所以在实际的调试中不管我如何丢弃开始的数据,总是有一个不相关的数据存在。之所以是猜测,是因为我现在还没有证实。在仿真中可以明显的看到,就算没有使能write_req_r, fifo写入的数据也能更新。

从仿真的波形可以看出:在data_in=1才使能write_req_r,在data_in=2,fifo才写入1 。 但是根据我的分析,应该要写入0。想想唯一不同只有这一句了:assign fifo_data_in = (i == 10'd7) ? data_read_1 : data_read_2;因为使用乒乓操作所以要做个选择。好的仿真看看。测试:如果 i 变化了且data_read_1和data_read_2有变化,但是write_req_r没有使能,观察fifo_data_in有没有变化即可。如果有变化证明我的猜测是错的。(没有仿真之前我不能确定,表明着我对verilog和数字电路的不理解,这也是我以后要加强的地方。)好吧下面是仿真的结果。

很显然:即使没有使能write_req_r,fifo_data_in也会变化在实际的仿真中我也使用了:

assign    fifo_data_in = flag_write ? fifo_data_in_r : counter;。可知我的猜测是错误的。还是不能猜的。那它为什么会多些一个当前数据的前一个存在fifo_data_in的中数据。

分析中。。。。。。。。。。。。。。。。。。。。。。。。有知道的,希望能留言。

呵呵,我还是想搞清楚到底是怎么回事。我使用了绝招,signaltap II 来看看在触发写,读的现场数据。

上图是:write_req_r下降沿触发是,但是的数据状态。明显的可以看到下降沿前后都是EB,因此可以确定肯定不是写的问题,这和前面的分析是一致的。(心里暗想,肯定是读的问题了。不然,我真的不知道怎么解决了)

上图是read_req_r下降沿触发时的数据。可以看到在使能的时候,data_out_r的值没有更新。虽然,现在还不知道原因,但是事实证明,问题就是出在这。(终于放心了。。。。)

现在来找找原因:(先使用modelsim仿真看看)

(嗯,和我开始的仿真是一样的)上图是modelsim的仿真图,可见不会读fifo_data[0]前的值,即输出是及时的更新的。奇怪了,怎么仿真和实际的情况不一样?我就去找,仿真和实际的不同点。

实际:data_tr_r <= fifo_data_out;

仿真:wire   fifo_data_out;

于是我就将仿真改成和实际的,加一个非阻塞的赋值。看看会不会,读的时候不会及时的更新。(希望是啊,不然我有不知道要如何解释了。呵呵。。。)

哈哈,,,)可以,真的是,改成和实际的一样时,真的要落后一个时钟。

我想想这是什么问题,就是对于阻塞赋值和非阻塞赋值的不理解造成的。实际却又不是,那是不是不能解决,只能丢掉第一次读的?(不能想当然啊)

仔细分析(还是要靠这个):

在fifo中的输出 :data_out_r <= fifo_data[read_addr];  assign   data_out = data_out_r;

在接收数据的时候:data_tr_r <= fifo_data_out; assign data_tr = data_tr_r;

可知,这可是存在两级的触发器的,所以开始要多打一拍,结束的时候要多打一拍。至此,问题可以说是分析好了。

呵呵,,,,,开心!

总结:

  要学会仿真的分析问题,而不是盲目的测试(耗时间,耗精力,还不会提高!)。

要扎实,认真。不能想当然。

最新文章

  1. SFC中的问题描述
  2. python设计模式
  3. 小表驱动大表, 兼论exists和in
  4. 自带openJDK,如何切换成Oracle JDK
  5. python collections defaultdict
  6. nginx 日志分割
  7. [LintCode] Find the Weak Connected Component in the Directed Graph
  8. php时间函数time(),date(),mktime()区别
  9. Tomcat 映射虚拟目录
  10. 利用SCI做的一个足球答题系统
  11. ubuntu下Django的下载与安装(三种方法)
  12. 关于Spark中RDD的设计的一些分析
  13. 如何讓Android系統顯示CJK擴展區漢字
  14. JavaScript 字符串(String) 对象
  15. 转 Android HTTPS详解
  16. KBEngine简单RPG-Demo源码解析(3)
  17. Object-C 里面的animation动画效果,核心动画
  18. GitLab简单使用
  19. 《java入门第一季》之好玩的正则表达式
  20. 【洛谷P2756】飞行员配对方案问题

热门文章

  1. oracle:与mysql相似得find_set_in函数用法
  2. JSON/JSONP浅谈
  3. hdu 5973 Game of Taking Stones(大数,bash game¥)
  4. ActionDescriptor 的认识
  5. Golang的接口
  6. ROS中使用ABB Yumi IRB14000的一些资料汇总
  7. 机器学习算法实现解析——libFM之libFM的训练过程之SGD的方法
  8. Markdown list状态下插入代码
  9. I.MX6 网卡能收不能发
  10. 转载:将STM32的标准库编译成lib使用【图文】