在异步FIFO中写入延迟后读取?

时间:2017-08-07 19:00:38

标签: verilog fpga fifo xilinx-ise

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

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

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

2 个答案:

答案 0 :(得分:2)

时钟关系是什么?假设你在6-7 clk1(快速时钟)周期中看到了延迟,那看起来就像你期望的那样取决于时钟关系clk1 / clk2。

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

您正在使用由clk1生成的wr_en来控制由clk2计时的rd_en。因此,现在wr_en用于两个时钟域,并且会导致metastability

简而言之,您没有正确使用AFIFO。当AFIFO为rd_en时,请尝试让clk2逻辑始终设置为!empty

答案 1 :(得分:2)

我认为您希望通过异步FIFO将一些同步到clk1的数据转换为同步到clk2。

首先,你不需要通过clk2直接对clk1同步信号进行采样。就像使用由clk1生成的wr_en一样来控制由clk2计时的rd_en。它会导致亚稳态.FIFO总是用来解决亚稳态问题。所以不需要像第二个一样阻止。

因此,如何正确使用异步FIFO成为问题。 你应该阅读像PG057这样的Xilinx FIFO发生器产品指南。你应该知道FIFO的理论和使用方法。否则你在使用FIFO时会有很多痛苦。

我的建议如下。 对于写操作,你需要同时使用almost_full和full信号以避免溢出。你可以在PG057图3-2中看到它。你需要使用almost_full,因为如果wr_en是连续的,那么完整信号慢1个时钟以避免溢出。 对于读操作,您需要同时使用almost_empty和empty信号,原因相同。 然后,您可以正确转换时钟区域。

原谅我的英语。