(一)同步FIFO

本文详细介绍了FIFO(先进先出)的工作原理,包括其对外接口、空满信号的产生方式以及同步FIFO的设计代码。同时,重点讨论了FIFO最小深度的计算方法,通过实例展示了在不同写读时钟频率下如何确定FIFO的最小深度以确保数据传输的正确性。此外,还提供了一个具体的问题,计算了在特定条件下FIFO的最小深度以满足异步FIFO的数据缓冲需求。
摘要由CSDN通过智能技术生成

一、FIFO:

即First-in-first-out,用于缓存数据的模块,对于同步FIFO数据写入FIFO的时钟和数据读出FIFO的时钟是同步的(synchronous)。

常用的对外接口:clk、rst_n、wr_en、rd_en、buf_in、buf_out、buf_full、buf_empty

FIFO深度:FIFO有多少个存储单元,一般读写指针位宽$clog2(FIFO_DEPTH);

FIFO宽度:一个存储单元写数据位宽是多少;

空满信号的产生一般有两种方式:

1、用一个计数器对读写数据的个数计数,为0就表示空,等于FIFO深度时就表示满;

2、利用读写指针,多定义一位读写位宽,最高位表示FIFO是否已经读写完成一圈;

wr_ptr:表示当前位置还未写

rd_ptr:表示当前位置还未读

FIFO设计代码:

module sync_fifo#(
	parameter BUF_WIDTH = 8,        //数据位宽
	parameter BUF_DEPTH = 8,		//数据个数,FIFO深度
	parameter PTR_WIDTH = 3 		//地址宽度为3
	)(
	input 			 clk       ,
	input 			 rst_n     ,
	input 			 wr_en     ,
	input 			 rd_en     ,
	input 	   [7:0] buf_in    ,    //data input to be pushed to buffer
	output reg [7:0] buf_out   ,	// port to output the data using pop
	output 			 buf_full  ,	// buffer full indication
	output 			 buf_empty  	// buffer empty indication
);
	//reg [PTR_WIDTH:0]	fifo_cnt;
	//reg [PTR_WIDTH-1:0] 	wr_ptr;
	//reg [PTR_WIDTH-1:0] 	rd_ptr;
	reg [PTR_WIDTH:0] 	wr_ptr;
	reg [PTR_WIDTH:0] 	rd_ptr;
	reg [BUF_WIDTH-1:0]	buf_mem[0:BUF_DEPTH-1];
	
	always @(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			wr_ptr <= {(PTR_WIDTH+1){1'b0}};	
		else if(wr_en && ~buf_full)
			wr_ptr <= wr_ptr + 1'b1;
	end
	
	always @(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			rd_ptr <= {(PTR_WIDTH+1){1'b0}};	
		else if(rd_en && ~buf_empty)
			rd_ptr <= rd_ptr + 1'b1;
	end
	
	/*always @(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			fifo_cnt <= {(PTR_WIDTH+1){1'b0}};
		else if((wr_en && ~buf_full) && (rd_en && ~buf_empty))
			fifo_cnt <= fifo_cnt;
		else if(wr_en && ~buf_full)
			fifo_cnt <= fifo_cnt + 1'b1;
		else if(rd_en && ~buf_empty)
			fifo_cnt <= fifo_cnt - 1'b1;
	end*/
	
	//assign buf_empty = (fifo_cnt == 0);
	//assign buf_full = (fifo_cnt == BUF_DEPTH);
	
	assign buf_full  = (wr_ptr[3] != rd_ptr[3])&&(wr_ptr[2:0] == rd_ptr[2:0]);
	assign buf_empty = (wr_ptr == rd_ptr);
	
	integer i;
	always @(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			for(i=0;i<=BUF_DEPTH-1;i=i+1)
				buf_mem[i] <= {(BUF_WIDTH){1'b0}};
		else if(wr_en && ~buf_full)
			buf_mem[wr_ptr[2:0]] <= buf_in;	
	end
	
	always @(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			buf_out <= {(BUF_WIDTH){1'b0}};
		else if(rd_en && ~buf_empty)
			buf_out <= buf_mem[rd_ptr[2:0]];
	end
	
endmodule

二、FIFO最小深度计算:(重点)

说明:

  • burst length:只有在突发数据传输过程中讨论FIFO深度才是有意义的,也就是说我们一次传递一包数据完成后再去传递下一包数据,我们把一段时间内传递的数据个数称为burst length。若FIFO无止境的写数据,那FIFO深度只有无穷大才能满足。
  • 要确定FIFO的深度,关键在于计算出在突发读写这段时间内有多少个数据没有被读走,即FIFO的最小深度就等于没有被读走的数据个数。

分几种情况:写读时钟为fa,fb,分fa>fb,fa<fb,fa==fb

举例:

假设:fa>fb
写数据时钟频率fa=80MHz
读数据时钟频率f,=50MHz
突发长度= number of data to be transferred = 120
每隔1个cycle写一次
每隔3个cycle读一次

那么:
每隔1个cycle写一次,意味着2个cycle才写一个数据
每隔3个cycle读一次,意味着4个cycle才读一个数据
写一个数据所需要的时间= 2*1/80MHz = 25ns
突发传输中,写完所有数据所需要的时间= 120*25ns = 3000ns
读一个数据所需要的时间=4*1/50MHz = 80ns
所以写完所有的突发传输数据需要花费3000ns
在3000ns内能够读走的数据个数= 300ons/80ns = 37.5
所以在300ons内还没有被读走的数据个数= 120-37.5 =82.5
因此FIFO的最小深度为83

假设:fa<fb
写数据时钟频率fa=40MHz
读数据时钟频率f=50MHz
突发长度= number of data to be transferred = 120
每隔1个cycle写一次
每隔3个cycle读一次

那么:
每隔1个cycle写一次,意味着2个cycle才写一个数据
每隔3个cycle读一次,意味着4个cycle才读一个数据
写一个数据所需要的时间=2*1/4OMHz = 50ns
突发传输中,写完所有数据所需要的时间= 120*50ns = 6000ns
读一个数据所需要的时间=4*1/50MHz = 80ns
所以写完所有的突发传输数据需要花费6000ns
在6000ns内能够读走的数据个数编辑ns/B0ns = 75
所以在6000ns内还没有被读走的数据个数=120-75= 45
因此FIFO的最小深度为45

另一种情况:没有给出突发长度时,采用背靠背方式传递数据,就是指连续写两次数据,假设中可以得出每100个周期就有40个数据写入FIFO,每10个周期可以有8个数据读出FIFO,数据是随机写入FIFO的,我们需要考虑做坏的情形,即写速率最大的情形,只有如下图背靠背的情形是写速率最高的情形,burst length为80。

注意:这里需要验证一下是否有解,即写入burst数据时间必须大于等于读出burst数据时间,不然数据就会越累积越多,使得FIFO的深度必须为无穷大。首先写入80个数据需要的时间=1/80MHz*(80*100/40)=2500ns,读出80个数据需要的时间= 1/50MHz*(80*10/8)-2000ns,由于写入burst数据时间大于对出burst数据时间,因此有解。
下面来计算FIFO最小深度,连续写入80个数据最快所需要时间=1/80MHz*80 = 1000ns从FIFO中读出一个数据至少所需时间=(1/50MHz)* (10/8)= 25ns
那么在1000ns内能够读出的数据= 1000ns/25ns = 40
在1000ns内没有读出的数据= 80 - 40 = 40
因此FIFO的最小深度为40

公式:

  • Burst_length :最大突发长度, 注意: 指在突发时间段, 写时钟 写入的数据长度
  • rd_rate:指一个周期读取的数据字节(byte),1字节 = 8 bit
一个8bit宽的FIFO,输入时钟为100MHz,输出时钟为95MHz,设一个package为4Kbit, 且两个package之间的发送间距足够大。问FIFO的最小深度。

异步FIFO,读写频率不同,读写位宽相同。发送一次Burst突发数据量为4000bit。
发送Burst的时间 T=4000/100MHz。
接收方接受的数据量 T*95MHz = 4000 * 95 / 100 bit
FIFO需要缓存的数据量 4000 - 4000 * 95 / 100 = 200bit
FIFO_Depth >= 200bit/8bit = 25。
那么FIFO的深度至少要大于等于25才行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值