Xilinx FIFO Generator 的 AXI-Stream 接口形式介绍

  以往使用 Xilinx 的 FIFO IP 核,往往使用 Native 的接口形式(wr_en, din[x:0], full; rd_en, dout[x:0], empty),这在大多数的情况下是方便的,然而在与某些具有 AXI 接口的其他 IP 配合使用时,Native 接口使用起来就不是很方便了。这种情况下,可以使用 FIFO IP 的 AXI-Stream (AXIS)接口形式,可以大大简化设计,本文对这一接口形式下的 FIFO Generator IP 进行介绍。

IP 配置

在这里插入图片描述

  要使用 AXIS 接口形式,需要在 IP 配置界面勾选 AXI Stream 接口类型,如上图所示。

在这里插入图片描述

第二页配置中,可配置 AXIS 的接口位宽。在 AXIS 接口形式下,数据位宽不能任意选择,其位宽以 8bits 为单位,TDATA NUM BYTES 指示了数据位宽为多少个字节。TUSER WIDTH 提供了可选的 tuser 位宽,通常用于指示发生一个错误或报文属于某一类型(例如三速 MAC IP 的帧过滤器输出)。勾选 TLAST 以启用 tlast 信号。

在这里插入图片描述

第三页可选 FIFO 的工作类型:Data FIFO、Packet FIFO,第一种是以单个数据为单位存储进 FIFO 的,第二种以数据包(Packet)为单位存储进 FIFO。其中 Packet FIFO 只有在 TLAST 启用的状态下才可以生成。除此之外,FIFO 深度、可编程空满标志以及 FIFO 元素计数也在这一页进行配置。

在这里插入图片描述

第四页配置是否启用 underflow、overflow 标志,只有在 Data FIFO 下才可以勾选。

  AXI-Stream 接口形式的数据接口分别为 S_AXIS 和 M_AXIS,S_AXIS 即数据写入端口,M_AXIS 即数据读取端口,如下图所示。

在这里插入图片描述

仿真

Data FIFO

  DATA FIFO 以单个数据为单位进行写入,数据写入不受 tuser 和 tlast 影响,m_tuser 和 m_tlast 分别标记 s_tuser 和 s_tlast 标记的数据。生成 256 深度的 AXI-Stream 接口形式的异步 Data FIFO,并编写 testbench 如下

`timescale 1ns/1ns
`default_nettype none
module FIFO_AXI_Stream_tb();

reg		clk_100M	= 1'b1;
reg		rst_n		= 1'b1;

always #5 begin
	clk_100M	<= ~clk_100M;
end

wire			FIFO_wr_rst_busy;		//这两个信号一直高阻是什么意思?也无法不生成
wire			FIFO_rd_rst_busy;

reg				s_axis_tvalid	= 1'b0;
wire			s_axis_tready;
reg		[7:0]	s_axis_tdata	= 8'd0;
reg				s_axis_tuser	= 1'b0;
reg				s_axis_tlast	= 1'b0;

wire			m_axis_tvalid;
reg				m_axis_tready	= 1'b0;
wire	[7:0]	m_axis_tdata;
wire			m_axis_tuser;
wire			m_axis_tlast;

//use tlast,Packet FIFO
FIFO_AXI_Stream FIFO_AXI_Stream(
	.s_aresetn		(rst_n),
	.wr_rst_busy	(FIFO_wr_rst_busy),
	.rd_rst_busy	(FIFO_rd_rst_busy),

	.s_aclk			(clk_100M),
	.s_axis_tvalid	(s_axis_tvalid),
	.s_axis_tready	(s_axis_tready),		//指示初始化完成,但不指示~full
	.s_axis_tdata	(s_axis_tdata),
	.s_axis_tuser	(s_axis_tuser),
	.s_axis_tlast	(s_axis_tlast),	

	.m_aclk			(clk_100M),
	.m_axis_tvalid	(m_axis_tvalid),		//相当于~empty
	.m_axis_tready	(m_axis_tready),
	.m_axis_tdata	(m_axis_tdata),
	.m_axis_tuser	(m_axis_tuser),
	.m_axis_tlast	(m_axis_tlast)
);

task wr_fifo;
	input	[15:0]	wr_num;
	input			en_tlast;
	input			en_tuser;

	integer i;
	begin
		wait(clk_100M);
		for(i = 0; i < wr_num; i = i + 1'b1) begin
			wait(~clk_100M);
			s_axis_tvalid	<= 1'b1;
			s_axis_tdata	<= s_axis_tdata + 1'b1;

			if(i == wr_num-1'b1 && en_tlast) begin
				s_axis_tlast	<= 1'b1;
			end
			else begin
				s_axis_tlast	<= 1'b0;
			end

			if(i==wr_num-1'b1 && en_tuser) begin
				s_axis_tuser	<= 1'b1;
			end
			else begin
				s_axis_tuser	<= 1'b0;
			end

			wait(clk_100M);
		end
		wait(~clk_100M);
		s_axis_tvalid	<= 1'b0;
		s_axis_tlast	<= 1'b0;
		s_axis_tuser	<= 1'b0;
		wait(clk_100M);
	end
endtask

task rd_fifo;
	input	[15:0]	rd_num;

	integer j;
	begin
		wait(clk_100M);
		for(j = 0; j < rd_num; j = j + 1'b1) begin
			wait(~clk_100M);
			m_axis_tready	<= 1'b1;
			wait(clk_100M);
		end
		wait(~clk_100M);
		m_axis_tready	<= 1'b0;
		wait(clk_100M);
	end
endtask

initial begin
	#10;
	rst_n	<= 1'b0;
	#100;
	rst_n	<= 1'b1;
	#100;

	wait(s_axis_tready);	//等待初始化完成
	#100;

	wr_fifo(16,0,1);
	#100;
	wr_fifo(16,1,0);
	#100;
	rd_fifo(40);			//测试读空
	#100;

	wr_fifo(32,1,0);
	#100;
	fork
		begin
			wr_fifo(64,1,1);
		end

		begin
			rd_fifo(64);
		end
	join 
	#100;
	rd_fifo(32);
	#100;

	wr_fifo(150,1,0);
	#100;
    wr_fifo(150,1,0);	//测试写满
	#100;

	rd_fifo(300);
	#100;

	#100;
	$stop;
end

endmodule

  仿真结果如下:

在这里插入图片描述

由于 Data FIFO 以单个数据为单位进行写入,因此当发生写满异常时,仅有超出 FIFO 深度部分的数据发生丢失。

Packet FIFO

  Packet FIFO 以数据包为单位进行写入,数据在 s_tlast 断言时才被统一写入 FIFO,写入不受 tuser 影响,m_tuser 和 m_tlast 分别标记 s_tuser 和 s_tlast 标记的数据。生成 256 深度的 AXI-Stream 接口形式的异步 Packet FIFO,testbench 与前面的相同。

  仿真结果如下:

在这里插入图片描述

由于Packet FIFO 以数据包为单位进行写入,因此当出现写满情况时(即 s_tlast 在 s_tready=Low 时断言)则这一组数据被整体舍弃,如本仿真的最后一组的写入所展示的那样。


参考文献

  • pg057-fifo-generator.pdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今朝无言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值