如何处理异步FIFO读取延迟?Xilinx FIFO核场景下避免数据丢失
针对Xilinx FIFO生成器核存在2个时钟周期读取延迟、M1拉低fifo_rd_en后不再接收数据导致的末尾数据丢失问题,以下是几种可行的解决方案:
方案1:提前控制
fifo_rd_en拉低时刻,延迟M1接收关闭时机
核心逻辑:当M1确定需要停止接收时,提前2个时钟周期拉低fifo_rd_en,同时保持M1的接收通路打开,持续2个周期,确保FIFO因最后一次fifo_rd_en触发的延迟数据能被正常接收。
举例:若M1需接收100个数据,在第98个数据被接收时就拉低fifo_rd_en,之后继续接收第99、100个延迟产生的数据,完成后再关闭M1的接收逻辑。方案2:在FIFO输出与M1之间插入2级缓冲寄存器
在FIFO的dout输出端串联一个2级移位寄存器(或小型同步FIFO),暂存延迟产生的数据。当M1拉低fifo_rd_en后,缓冲寄存器中已存储的2个数据可继续输出给M1,避免丢失。
逻辑示例(Verilog):reg [DATA_WIDTH-1:0] buf_reg [1:0]; always @(posedge clk) begin buf_reg[0] <= fifo_dout; buf_reg[1] <= buf_reg[0]; if (m1_recv_en) begin m1_data_in <= buf_reg[1]; end end注:需配合
fifo_rd_en与M1接收使能的同步逻辑,确保缓冲数据被完整读取。方案3:基于FIFO空标志与延迟计数器的
fifo_rd_en控制
引入中间控制模块接管fifo_rd_en:- 当M1发出停止请求时,不立即拉低
fifo_rd_en,启动一个2周期的计数器; - 同时监测FIFO的
empty信号,当计数器溢出且empty有效时,再拉低fifo_rd_en; - 计数器运行的2个周期内,保持M1接收通路打开,接收延迟输出的数据。
- 当M1发出停止请求时,不立即拉低
方案4:修改FIFO核的读取模式配置
若项目允许调整FIFO参数,可将Xilinx FIFO生成器配置为First-Word-Fall-Through(FWFT)模式。该模式下,FIFO读取延迟可降低至1个时钟周期(非空时数据预置于输出端),部分配置甚至能实现0延迟读取,从根源减少数据丢失风险。
注:需结合项目时序、资源占用需求评估适用性。方案5:使用
dout_valid信号同步接收逻辑
利用Xilinx FIFO核输出的dout_valid信号(部分配置可生成),让M1仅在dout_valid有效时接收数据:- M1拉低
fifo_rd_en后,继续监听dout_valid; - 只要
dout_valid为高,就保持M1接收逻辑开启,直到dout_valid变低,确认延迟数据全部接收完毕后再关闭通路。
- M1拉低
内容的提问来源于stack exchange,提问作者Surya Narayana

