zoukankan      html  css  js  c++  java
  • 关于双独立时钟fifo的一些细节探讨

       最近遇到一个项目,就是接收数据转换成本地数据。两个时钟是频率是基本一样,但是存在5%偏差,而且存在相位差。

     这是基本需求。一般转换的办法就是fifo写入有效数据,然后用empty读取出来。但是发现有个问题。就是如果两个帧之间间隔太短了,会导致读取的时候,两帧的数据会连续成一帧数据。解决办法就是把写使能也要加入到fifo中,把前后使能无效+数据,也是写入到fifo,恢复的时候再恢复到有效数据。

    wire wrfifo_wren;
    assign wrfifo_wren = serdes_en_d2 | serdes_en;

    wire[32:0] wrfifo_wrdata;
    assign wrfifo_wrdata = { serdes_en_d0,rx_data_lock_d0};

        二个关于频率偏差问题,很多人都是内部count 来判断,好在xilinx由prog-empty,可以编程的empty,选择两个状态。这样在拉低信号,判断fifo是否写入数据,再读取。

          .prog_empty(fifo_almost_empty)
       );
      
     reg fifo_almost_empty_d0;
     reg fifo_almost_empty_d1;
     reg fifo_almost_empty_d2;
     reg fifo_almost_empty_d3;
     reg fifo_almost_empty_d4;
      always @(posedge    ref_clk)
     begin
        fifo_almost_empty_d0 <= fifo_almost_empty;
        fifo_almost_empty_d1 <= fifo_almost_empty_d0;
        fifo_almost_empty_d2 <= fifo_almost_empty_d1;
        fifo_almost_empty_d3 <= fifo_almost_empty_d2;
        fifo_almost_empty_d4 <= fifo_almost_empty_d3;
     end
     
     reg fifo_rd_en_temp ;
     always @(posedge    ref_clk)
     begin
        if( fifo_almost_empty_d4 == 0)
            fifo_rd_en_temp <= 1;
         else if( fifo_empty)
            fifo_rd_en_temp <= 0; 
      end 

    三个问题,fifo其中写的时钟会波动,中途可能会停掉,因为上电复位过程会停止时钟,中途也会停止时钟。很多fifo对这个时钟是没有讲解的,发现的现象竟然是full信号一直为慢的信号。empty也是空的信号,后面的数据根本写入不了。解决办法就是,直接判断full信号,复位fifo。这样稳定时钟又可以写入数据。

    注意同步复位,要求是最慢的时钟的三个时钟以上有效。

    wire lock_fail_rising;
    assign lock_fail_rising = (( lock_fail_temp_d1 == 1'b0) & (lock_fail_temp_d0 ==1'b1));

    wire       fifo_full;
    reg fifo_full_d0;
    reg fifo_full_d1;
    reg fifo_full_d2;
    always @(posedge    ref_clk)
    begin
        fifo_full_d0 <= fifo_full;
        fifo_full_d1 <= fifo_full_d0;
        fifo_full_d2 <= fifo_full_d1;
    end
    reg lock_fail_rising_d0;
    reg lock_fail_rising_d1;
    reg lock_fail_rising_d2;
    reg lock_fail_rising_d3;
    reg lock_fail_rising_d4;
    reg lock_fail_rising_d5;
    reg lock_fail_rising_d6;
    always @(posedge    ref_clk)
    begin
        lock_fail_rising_d0 <= lock_fail_rising| fifo_full_d2 ;
        lock_fail_rising_d1 <= lock_fail_rising_d0;
        lock_fail_rising_d2 <= lock_fail_rising_d1;
        lock_fail_rising_d3 <= lock_fail_rising_d2; 
        lock_fail_rising_d4 <= lock_fail_rising_d3; 
        lock_fail_rising_d5 <= lock_fail_rising_d4; 
        lock_fail_rising_d6 <= lock_fail_rising_d5; 
    end


    assign rd_rst = lock_fail_rising_d6 | lock_fail_rising_d0;

  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/fpga-design/p/14187393.html
Copyright © 2011-2022 走看看