2017-08-07 636 views
1

我正试图将模块与由Xilinx CORE Generator生成的异步FIFO进行接口。但是,我观察到AFIFO输入端口提供的数据(虽然正确)在6-7个时钟周期的延迟之后开始出现在dout上。这是预期的吗?或者我做错了什么?我所做的是断言AFIFO的write_enable引脚,提供输入数据,然后在下一个周期断言read_enable引脚。但仍存在延迟问题。任何帮助表示赞赏。在异步FIFO中写入延迟后读取?

编辑:我附上我的代码的一部分。

always @ (posedge clk1, posedge rst)//faster clock domain 
begin 
    if (rst) 
     wr_en<= 1'b 0; 

    else 
     begin 
      if (data_wrt) 
       begin 
       wr_en<= 1'b 1;       
       end 
      else 
       wr_en<= 1'b 0; 
     end 
end 
always @ (negedge clk2, posedge rst)//slower clock domain 
    begin 
     if (rst) 
      rd_en<= 1'b 0; 

     else 
      begin 
       if (wr_en) 
        begin 
        rd_en<= 1'b 1;        
        end 
       else 
        rd_en<= 1'b 0;    
      end 

    end 
AFIFO AFIFO1(//AFIFO module instantiation 
    .din(data_in), 
    .rd_clk(clk2), 
    .rd_en(rd_en), 
    .rst(reset), 
    .wr_clk(clk1), 
    .wr_en(wr_en), 
    .dout(data_out), 
    .empty(empty), 
    .full(full) 
    ); 

AFIFO Input Output

AFIFO2

+1

任何代码片段? – Serge

+0

如果你的'clk2'比'clk1'慢,你的'rd_en'触发器可能会丢失一些使能信号(在'if(wr_en)'块中)。 –

+0

那我该怎么办? – Candy

回答

2

什么是时钟的关系?假设您看到6-7 clk1(快速时钟)周期中的延迟,这看起来像您期望的一样,具体取决于时钟关系clk1/clk2。

也就是说,异步FIFO的要点通常是充当从一个时钟域到另一个时钟域的同步器。只要未满,写时钟域(clk1)就会将数据写入AFIFO。只要AFIFO不为空,读时钟域(clk2)就会读取新数据。你在这里做的是打破这种用法。

您正在使用由clk1生成的wr_en来控制由clk2提供时钟的rd_en。所以现在在两个时钟域中都使用wr_en,并且会导致metastability

因此,总之,您没有正确使用AFIFO。尝试改为在AFIFO为!empty时,始终将clk2逻辑设置为rd_en

+0

我已经用AFIFO上传了我的模拟屏幕截图。 – Candy

+0

在这张图片中,有一些东西看起来有点奇怪。首先我会说,你看到的延迟比我想象的要大得多。六个慢时钟周期似乎过多。这可能是在FIFO发生器中可控的。其次,'empty'和'data_out'似乎不与clk2同步,而是延迟了1/4周期。然而,这可能是模拟延迟,也是FIFO发生器的一部分。 最后,当它不应该被启用时,你仍然启用'rd_en'。只要'empty'很高,'rd_en'不应该高。 – Hida

+0

我也上传了第二张截图,当AFIFO为空时,rd_en被激活。现在我在data_out上出错了第一个值!在模拟时出现以下警告:错误:C:/Xilinx/verilog/src/simprims/X_RAMB16_S36_S36.v(2655):$ setup(posedge DIA [1] && dia_enable:127784 ps,posedge CLKA:127972 ps,484 ps); #时间:127972 ps迭代次数:3实例:/tb/uut/\AFIFO1/BU2/U0/grf.rf/mem/gbm.gbmg.gbmga.ngecc.bmg/blk_mem_generator/valid.cstr/ramloop[0]。 ram.r/v2_noinit.ram/dp36x36.ram \ – Candy

2

我想你想通过异步FIFO将一些数据同步到clk1以同步到clk2。首先,你不需要通过clk2直接采样与clk1同步的信号。就像使用clk1产生的wr_en来控制由clk2计时的rd_en一样,它会引起亚稳态.FIFO总是用来求解亚稳态问题。所以不需要做第二个总是阻塞的问题。

所以问题是如何正确使用异步FIFO。 您应该阅读Xilinx FIFO生成器产品指南(如PG057)。您应该了解FIFO的理论和使用方法。否则使用FIFO时您会感到非常痛苦。

我的建议如下。 对于写入操作,您需要使用almost_full和full信号来避免溢出。您可以在PG057中看到它(图3-2)。您需要使用almost_full,因为如果wr_en连续,则完整信号比aviod溢出慢1个时钟。 对于读取操作,您需要同时使用almost_empty和空信号。 然后,您可以正确转换时钟区域。

原谅我的英语。