标准FIFO
本文使用位扩展的方式实现标准FIFO,原理可参考【AXIS】AXI-Stream FIFO设计实现(一)——基本模式,核心代码如下:
logic [FIFO_DEPTH_WIDTH : 0] rd_ptr_r = 'd0, wr_ptr_r = 'd0;always_ff @(posedge clk) beginif (wr_en & ~wfull) beginwr_ptr_r <= wr_ptr_r + 1;endend always_ff @(posedge clk) beginif (rd_en & ~rempty) beginrd_ptr_r <= rd_ptr_r + 1;endendassign wfull = (wr_ptr_r[FIFO_DEPTH_WIDTH] != rd_ptr_r[FIFO_DEPTH_WIDTH]) && (wr_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0] == rd_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0]);assign rempty = rd_ptr_r == wr_ptr_r;logic [TDATA_WIDTH - 1 : 0] ram[FIFO_DEPTH - 1 : 0];always @(posedge clk) beginif (wr_en & ~wfull) beginram[wr_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0]] <= m_axis_tdata;endendalways @(posedge clk) beginif (rd_en & ~rempty) begins_axis_tdata <= ram[rd_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0]];endend
FWFT FIFO简单实现
基于标准FIFO,引入FWFT机制。一种简单做法即将ram输出改为组合逻辑输出,这种方式实现的FWFT延时最低。
always_comb begin// if (rd_en & ~rempty) begins_axis_tdata = ram[rd_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0]];// endend
FWFT FIFO优化
然而,在FPGA中所有存储资源如(BRAM、URAM)均具有一个周期的读延时,在构造大容量fifo时,为了让综合工具将FIFO存储RAM综合为BRAM / URAM,更合适的做法为添加寄存器slice,这种方式会增加1个周期的延迟:
initial rempty = 1'b1;assign wfull = sfifo_wfull;always_ff @(posedge clk) beginif (~sfifo_rempty & (rempty | rd_en)) begins_axis_tdata <= ram[rd_ptr_r[FIFO_DEPTH_WIDTH - 1 : 0]];endendassign sfifo_rd_en = (rempty | rd_en);always @(posedge clk) beginif (~sfifo_rempty) beginrempty <= 1'b0;end else if (rd_en) beginrempty <= 1'b1;endend
完整代码
完整工程代码可在同名微信公众号回复SYNC_FIFOs下载。