我正在尝试将模块与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)
);
答案 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信号,原因相同。 然后,您可以正确转换时钟区域。
原谅我的英语。