zoukankan      html  css  js  c++  java
  • FPGA SD 卡 之 乒乓操作 、同步fifo

    这里记录一个实际的需要使用乒乓操作的例子:读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;

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

    呵呵,,,,,开心!

     

     

    总结:

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

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

  • 相关阅读:
    蓝桥杯训练 2n皇后问题
    AtCoder Grand Contest #026 B
    AtCoder Grand Contest #026 A
    AtCoder Beginner Contest 103
    7-26 单词长度(15 分)
    uva 10006 Carmichael Numbers
    java并发带返回结果的批量任务执行(CompletionService:Executor + BlockingQueue)
    并发容器之CopyOnWriteArrayList
    模板模式
    静态工具类中使用注解注入service
  • 原文地址:https://www.cnblogs.com/cornhill/p/3920290.html
Copyright © 2011-2022 走看看