前文介绍了几种同步时钟情况下的AXI Stream FIFO实现方式,一般来说,FIFO也需要承担异步时钟域模块间数据传输的功能,本文介绍异步AXIS FIFO的实现方式。
如前文所说,AXI-Stream FIFO十分类似于FWFT异步FIFO,推荐参考前文FWFT异步FIFO的实现方式【FIFO】Standard / FWFT FIFO设计实现(二)——异步时钟,也可以参考同步AXIS FIFO的实现方式【AXIS】AXI-Stream FIFO设计实现(一)——基本模式。
对于已经实现好的FWFT FIFO,只进行些许调整,将其写FIFO信号wr_en替换为s_axis_tvalid,将FIFO写满信号wfull替换为s_axis_tready,将读FIFO信号rd_en替换为m_axis_tvalid,将FIFO读空信号rempty替换为m_axis_tready。
`timescale 1ns / 1ps
module async_axis_fifo_tb(
);
localparam TDATA_WIDTH = 4;
bit m_clk;
bit s_clk;
bit [TDATA_WIDTH - 1 : 0] m_axis_tdata;
bit m_axis_tvalid; // wr_en
bit m_axis_tready; // ~wfull
bit [TDATA_WIDTH - 1 : 0] s_axis_tdata;
bit s_axis_tvalid; // ~rempty
bit s_axis_tready;
always #5 m_clk = ~m_clk;
always #7 s_clk = ~s_clk;
logic [TDATA_WIDTH - 1 : 0] send_queue[$], recv_queue[$];
always_ff @(posedge m_clk) begin
if (~m_axis_tvalid) begin
`ifdef FLOW
m_axis_tvalid <= 1;
`else
m_axis_tvalid <= $random();
`endif
m_axis_tdata <= $random();
end else if (m_axis_tvalid & m_axis_tready) begin
`ifdef FLOW
m_axis_tvalid <= 1;
`else
m_axis_tvalid <= $random();
`endif
m_axis_tdata <= $random();
end
end
initial begin
forever begin
if (m_axis_tvalid & m_axis_tready) begin
send_queue.push_back(m_axis_tdata);
end
@(posedge m_clk);
end
end
initial begin
forever begin
if (s_axis_tvalid & s_axis_tready) begin
recv_queue.push_back(s_axis_tdata);
end
if (send_queue.size != 0 && recv_queue.size != 0) begin
if (send_queue[0] == recv_queue[0]) begin
send_queue.pop_front();
recv_queue.pop_front();
end else begin
$error();
$stop();
end
end
@(posedge s_clk);
end
end
always_ff @(posedge s_clk) begin
`ifdef FLOW
s_axis_tready <= 1;
`else
s_axis_tready <= $random();
`endif
end
logic wfull, rempty;
assign m_axis_tready = ~wfull;
assign s_axis_tvalid = ~rempty;
async_fifo_huge #(
.TDATA_WIDTH (TDATA_WIDTH ),
.FIFO_DEPTH (4) // 2 ** n
) async_fifo_huge_inst(
.m_clk(m_clk),
.s_clk(s_clk),
.m_axis_tdata(m_axis_tdata),
.wr_en(m_axis_tvalid),
.wfull(wfull),
.s_axis_tdata(s_axis_tdata),
.rempty(rempty),
.rd_en(s_axis_tready)
);
endmodule
下图展示了通过调整利用FWFT FIFO作为AXI Stream FIFO进行数据传输的仿真波形,其中上半部分为FWFT FIFO,下半部分为AXIS Stream输入激励。