当前位置:   article > 正文

IP核之FIFO_fifo ip核

fifo ip核

部分转载~
FIFO:First Input First Output,即先入先出队列,在计算机中,先进先出队列是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。
主要功能包括:
(1)数据的缓冲。如果数据的写入速率高,但间隔大,且会有突发;读出速率小,但相对均匀。则通过设置相应深度的FIFO,可以起到数据暂存的功能,且能够使后续处理流程平滑,避免前级突发时,后级来不及处理而丢弃数据。
(2)时钟域的隔离。对于不同时钟域的数据传递,则数据可以通过FIFO进行隔离,避免跨时钟域的数据传输带来的设计与约束上的复杂度。
(3)不同宽度的数据接口。例如单片机8位数据输出,而DSP是16位数据输入,在单片机和DSP连接时就可以使用FIFO来达到数据匹配的目的。

example:
当模块A要发送数据给模块B,其中模块A的工作时钟是100MHz,模块B的工作时钟是80MHz。若要直接讲A数据送给B,由于时钟不同,B模块势必会丢失数据或多采集数据。
解决问题的方案:使用FIFO,由于FIFO内部可以做跨时钟域处理,读写时钟可以不同,因此非常适合解决这类问题。
在这里插入图片描述
如图所示,模块C的功能如下:
a. 模块内部包含一个FIFO,该FIFO数据位宽16bit,深度是64,有rdusedw、wrusedw、empty等指示信号。
b. 输入数据data_in和data_in_vld都是输入clk_in时钟域的,模块首先将数据写入到内部FIFO中,等待被模块B读取。
c. 如果内部FIFO快满时(wrusede>=61),仍然有数据要写入,为了防止FIFO溢出,丢弃该数据,不再写入FIFO。
d. Data_out、data_out_vld和b_rdy都属于clk_out时钟域的。
e. b_rdy是模块B产生的接收数据准备好信号,当此信号为1时,表示模块B已经准备好接收数据,本模块可以将数据发送给模块B。如果为0,表示未准备好,不能将数据发送给模块B。
f. 当b_rdy为1时,且FIFO内有数据(rdempey==0)时,将数据送给模块B。
使用FIFO时要保证当FIFO已经处于满状态时,就不再往FIFO里写数据;当FIFO处于空状态时,不再读FIFO的数据。

基于Vivdao的FIFO IP核使用实例
1、打开IP Catalog–>搜索fifo—>选择FIFO Generator
在这里插入图片描述

2、打开FIFO IP核的配置界面
在这里插入图片描述
Vivado的IP一般分为以下几个步骤:

  • Component Name:IP名称
  • Basic:基本设置
  • Native Ports:本地端口
  • Status Flags:标志位
  • Data Counts:数据数量
  • Summary:总结

一、Basic 基本设置
(1)IP核的一般命名规则:同步/一般_fifo_数据位宽_数据深度
(2) Interface Type:端口类型。一般选择第一个,AXI是Xilinx特有的高速接口。
(3)Fifo Implementation:FIFO的实现方式。
FIFO实现方式有Common Clock同步和Independent Clocks异步两种,每种FIFO下有四种存储形式:

  1. Block RAM:使用FGPA内部的RAM。
  2. Distributed RAM:分布式RAM,使用内部的LUT和逻辑电路组成的fifo。
  3. Shift Register:移位寄存器形式,深度不大于32时可以使用。
  4. Build-in:内部自带的fifo,深度大于128可以使用。

二、Native Ports本地接口
在这里插入图片描述
在这里插入图片描述

1.Read Mode读模式

  • Standard FIFO:标准FIFO。选择这个模式,读出的数据会之后使能信号1个时钟周期,第1个数据先暂存在存储单元中,当信号变为高电平后,下1个时钟周期输出;

  • First Word Fall Through:简称FWFT FIFO。第1个数据直接送入输出缓冲区,并保持在输出总线上,当读信号变为高电平后,当前周期输出第1个数据,第2个周期输出第2个数据。
    第1个写入数据将被从ram中提前读出到读数据线,第1个数据有效与empty无效同时,即当信号有效后,读数据线将显示下一个数据地址(读出的数据与读使能信号同一个时钟周期)
    在这里插入图片描述

  • Data Port Parameters 数据接口参数
    write width 写宽度
    write depth 写深度
    read width 读宽度
    read depth 读深度
    (后面读的设置通常与写的设置相同)

  • Initialization 初始化
    Reset Pin 复位引脚
    Enable Safety Circuit 启用安全电路,一般都要选上
    Reset Type 复位类型,有两种:异步复位和同步复位
    Full Flag Reset Value 复位的值,0为低电平复位,1为高电平复 位

三、Status Flag 标志位设置
在这里插入图片描述
在这里插入图片描述

  • Optional flag 选择的标志
    Almost Full Flag 几乎满标志位
    Almost Empty Flag 几乎空标志
  • Handshakiing Options 握手选项,用于设置什么时候读,什么时候写
    write port handshaking 写握手选项
    write acknowledge 写标志位 分为高有效和低有效
    overflow 溢出标志 分为高有效和低有效
    read port handshaking 写握手选项
    valid flag 有效读 分为高有效和低有效
    underflow flag 读空标志位 分为高有效和低有效
  • Programmable Flags 自定义标志位 用于自定义什么时候写满和什么时候读空的标准,可编程满或空,推荐使用可编程满或空指示信号,用于保证整包数据写入,避免数据包内的数据丢失。为保证fifo运行的可靠性,尽量多保留些阈值。
    (1)Programmable Full Type 可编程写满类型
  • No Programmable Full Threshold 不采用可编程满
  • Single Programmable Full Threshold Constant 单个门限值,将门限确认和失效门限设置为同一个值
  • Multiple Programmbale Full Threshold Constants 单独控制PROG_FULL_THRESH_ASSERT和PROG_FULL_THRESH_NEGATE
    (2)Full Threshold Assert Value 可编程满门限确认,可选端口,用于设置可编程满标记使用的确认门限,可以在复位时动态设置;拉高prog_full信号当FIFO中数据的数量大于这个值的时候。
    (3) Full Threshold Negate Value 可编程满门限失效,可选端口,用于设置可编程满标记使用的失效门限,可以在复位时动态设置;拉低prog_full信号当FIFO中数据的数量小于这个值的时候。
    (4)Programmable Empty Type 可编程空门限,可选端口,这个信号用于输出使可编程空标记(prog_empty)确认或失效的门限值,门限值可以在复位期间动态设置。
  • No Programmalbe Empty Threshold 不采用可编程读空
  • Single Programmable Empty Threshold Constant 可编程空门限,将确认门限和失效门限设置为同一个值,用PROG_EMPTY_THRESH
  • Multiple Programmbale Empty Threshold Constants 单独控制PROG_EMPTY_THRESH_ASSERT和PROG_EMPTY_THRESH_NEGATE
    (5) Empty Threshold Assert Value 可编程空门限确认,可选端口,用于设置可编程空标记使用的确认门限,可以在复位时动态设置;prog_empty拉高,当FIFO中存的数据数量小于这个值。
    (6) Empty Threshold Negate Value可编程空门限失效,可选端口,用于设置可编程满标志使用的失效门限,可以在复位时动态设置;prog_empty拉低,当FIFO中存的数据数量大于这个值。

四、Data Counts:数据数量
尽量不采用读/写计数,因为它采用二级制划分存储容量,会导致区分的颗粒度较大。
在这里插入图片描述

五、Summary 总结
在这里插入图片描述

对FIFO进行读写的逻辑设计:

module fifo_read_write(
input	wire		sclk	,
input	wire		rst_n	,
input	wire [7:0]  datain	,
input	wire		data_v	,
input	wire		r_flag	,
output	wire [7:0]	dout
);
wire	almost_full,wr_ack,overflow,almost_empty,valid,underflow,prog_full,prog_empty;
wire	w_full,r_empty;
wire	wr_en;
wire	rd_en;

assign	wr_en = (~w_full) & data_v;
assign	rd_en = (~r_empty) & r_flag;


fifo_generator_0  U1(
  .clk				(		sclk				)		,
  .srst				(		rst_n			)		,
  .din				(		datain				)		,
  .wr_en			(		wr_en			)		,
  .rd_en			(		rd_en			)		,
  .dout				(		dout			)		,
  .full				(		w_full			)		,
  .almost_full		(		almost_full		)		,
  .wr_ack			(		wr_ack			)		,
  .overflow			(		overflow		)		,
  .empty			(		r_empty			)		,
  .almost_empty		(		almost_empty	)		,
  .valid			(		valid			)		,
  .underflow		(		underflow		)		,
  .prog_full		(		prog_full		)		,
  .prog_empty		(		prog_empty		)		
);


endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

testbench

`timescale	1ns/1ns
module	tb_fifo_read_write;
reg			sclk,rst_n;
reg			data_v;
reg			r_flag;
reg	[7:0]	datain;
wire [7:0]	dout;

initial	begin
	sclk = 0;
	rst_n = 1;
	#10000;
	rst_n = 0;
end

initial	begin
	data_v = 0;
	datain = 0;
	r_flag = 0;
	#20000;
	send_data();
	#60;
	read_data();
end

always	#10 sclk = ~sclk;

fifo_read_write tb_fifo_read_write(
		.sclk		(	sclk			)	,
		.rst_n		(	rst_n			)	,
		.datain		(	datain			)	,
		.data_v		(	data_v			)	,
		.r_flag		(	r_flag			)	,
		.dout	    (	dout			)	
);
task	send_data;
	integer	i;
	begin
		for(i=0; i<400; i=i+1)
			begin
				@(posedge	sclk)
					data_v = 1'b1;
					datain = i;
			end
			@(posedge	sclk)
				data_v = 1'b0;
				datain = 0;
	end
endtask

task	read_data;
		integer	i;
		begin
			for(i=0;i<259;i=i+1)	
				begin
					@(posedge	sclk)
					r_flag = 1'b1;
				end
			@(posedge sclk)
			data_v = 1'b0;
		end
endtask

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

仿真波形图:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/452359?site
推荐阅读
相关标签
  

闽ICP备14008679号