建材秒知道
登录
建材号 > 设计 > 正文

什么是FIFO

坚强的高跟鞋
细心的宝贝
2023-02-28 07:57:37

什么是FIFO

最佳答案
单身的彩虹
舒服的雪糕
2025-07-05 22:22:08

FIFO是First Input First Output的缩写,先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。

是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单。

但缺点就是只能顺序写入数据,顺序读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

最新回答
任性的山水
强健的太阳
2025-07-05 22:22:08

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。3.FIFO的一些重要参数FIFO的宽度:也就是英文资料里常看到的THE WIDTH,它只的是FIFO一次读写操作的数据位,就像MCU有8位和16位,ARM 32位等等,FIFO的宽度在单片成品IC中是固定的,也有可选择的,如果用FPGA自己实现一个FIFO,其数据位,也就是宽度是可以自己定义的。FIFO的深度:THE DEEPTH,它指的是FIFO可以存储多少个N位的数据(如果宽度为N)。如一个8位的FIFO,若深度为8,它可以存储8个8位的数据,深度为12 ,就可以存储12个8位的数据,FIFO的深度可大可小,个人认为FIFO深度的计算并无一个固定的公式。在FIFO实际工作中,其数据的满/空标志可以控制数据的继续写入或读出。在一个具体的应用中也不可能由一些参数算数精确的所需FIFO深度为多少,这在写速度大于读速度的理想状态下是可行的,但在实际中用到的FIFO深度往往要大于计算值。一般来说根据电路的具体情况,在兼顾系统性能和FIFO成本的情况下估算一个大概的宽度和深度就可以了。而对于写速度慢于读速度的应用,FIFO的深度要根据读出的数据结构和读出数据的由那些具体的要求来确定。满标志:FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出(overflow)。空标志:FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出(underflow)。读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。读指针:指向下一个读出地址。读完后自动加1。写指针:指向下一个要写入的地址的,写完自动加1。读写指针其实就是读写的地址,只不过这个地址不能任意选择,而是连续的。4.FIFO的分类根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。5.FIFO设计的难点FIFO设计的难点在于怎样判断FIFO的空/满状态。为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。在空的状态下不能进行读操作。怎样判断FIFO的满/空就成了FIFO设计的核心问题。由于同步FIFO几乎很少用到,这里只描述异步FIFO的空/满标志产生问题。 补充: 在用到触发器的设计中,不可避免的会遇到亚稳态的问题(关于亚稳态这里不作介绍,可查看相关资料)。在涉及到触发器的电路中,亚稳态无法彻底消除,只能想办法将其发生的概率将到最低。其中的一个方法就是使用格雷码。格雷码在相邻的两个码元之间只由一位变换(二进制码在很多情况下是很多码元在同时变化)。这就会避免计数器与时钟同步的时候发生亚稳态现象。但是格雷码有个缺点就是只能定义2^n的深度,而不能像二进制码那样随意的定义FIFO的深度,因为格雷码必须循环一个2^n,否则就不能保证两个相邻码元之间相差一位的条件,因此也就不是真正的各雷码了。第二就是使用冗余的触发器,假设一个触发器发生亚稳态的概率为P,那么两个及联的触发器发生亚稳态的概率就为P的平方。但这回导致延时的增加。亚稳态的发生会使得FIFO出现错误,读/写时钟采样的地址指针会与真实的值之间不同,这就导致写入或读出的地址错误。由于考虑延时的作用,空/满标志的产生并不一定出现在FIFO真的空/满时才出现。可能FIFO还未空/满时就出现了空/满标志。这并没有什么不好,只要保证FIFO不出现overflow or underflow 就OK了。很多关于FIFO的文章其实讨论的都是空/满标志的不同算法问题。在Vijay A. Nebhrajani的《异步FIFO结构》一文中,作者提出了两个关于FIFO空/满标志的算法。第一个算法:构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都相等时,FIFO为满(在Clifford E. Cummings的文章中以格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相等时,FIFO为空。这也许不容易看出,举个例子说明一下:一个深度为8字节的FIFO怎样工作(使用已转换为二进制的指针)。FIFO_WIDTH=8, 补充: FIFO_DEPTH= 2^N = 8,N = 3,指针宽度为N+1=4。起初rd_ptr_bin和wr_ptr_bin均为“0000”。此时FIFO中写入8个字节的数据。wr_ptr_bin =“1000”,rd_ptr_bin=“0000”。当然,这就是满条件。现在,假设执行了8次的读操作,使得rd_ptr_bin =“1000”,这就是空条件。另外的8次写操作将使wr_ptr_bin 等于“0000”,但rd_ptr_bin 仍然等于“1000”,因此FIFO为满条件。显然起始指针无需为“0000”。假设它为“0100”,并且FIFO为空,那么8个字节会使wr_ptr_bin =“1100”,, rd_ptr_bin 仍然为“0100”。这又说明FIFO为满。若写指针的高两位MSB大于读指针的高两位MSB则FIFO为“几乎空”。在Vijay A. Nebhrajani的《异步FIFO结构》第三部分的文章中也提到了一种方法,那就是方向标志与门限。设定了FIFO容量的75%作为上限,设定FIFO容量的25%为下限。当方向标志超过门限便输出满/空标志,这与Clifford E. Cummings的文章中提到的STYLE #2可谓是异曲同工。他们都属于保守的空满判断。其实这时输出空满标志FIFO并不一定真的空/满。说到此,我们已经清楚地看到,FIFO设计最关键的就是产生空/满标志的算法的不同产生了不同的FIFO。

火星上的宝贝
热心的鸭子
2025-07-05 22:22:08

异步清零,是指与时钟不同步,即清零信号有效时,无视触发脉冲,立即清零;同步清零是时钟触发条件满足时检测清零信号是否有效,有效则在下一个时间周期的触发条件下,执行清零。

例如74LS161采用异步清零,而74LS162,74LS163采用的是同步清零。在同步清零的计数器电路中,RD‘出现低电平后要等下一个CLK信号到达时才能将触发器清零。而在异步清零的计数器电路中,只要RD’出现低电平,触发器立即被置零,不受CLK的控制。

扩展资料:

在芯片初始化完成后,触发器内部各模块是处于复位状态,因此需要依次清零释放,其中就通过FIFO的异步清零与同步清零两种清零方式进行释放。在IC设计中,是不允许FIFO溢出的,但是一旦有溢出必须有中断上报机制。

在一些FIFO设计中,读端口非空即读,且读时钟频率大于写时钟,此种情况下,在正常工作状态,FIFO不会溢出,因此此类FIFO没有反压流控和溢出中断上报机制。

若先清零释放写端口,则数据会不断写入到FIFO中,而此时读端口没有清零,这段时间内可能会发生FIFO溢出并且没有任何信息上报,因此不合理。

执着的花瓣
温暖的睫毛膏
2025-07-05 22:22:08

FIFO( First Input First Output)简单说就是指先进先出。由于微电子技术的飞速发展,新一代FIFO芯片容量越来越大,体积越来越小,价格越来越便宜。作为一种新型大规模集成电路,FIFO芯片以其灵

活、方便、高效的特性,逐渐在高速数据采集、高速数据处理、高速数据传输以及多机处理系统中得到越来越广泛的应用。

在系统设计中,以增加数据传输率、处理大量数据流、匹配具有不同传输率的系统为目的而广泛使用FIFO存储器,从而提高了系统性能。FIFO存储器是一个先入先出的双口缓冲器,即第一个进入其

内的数据第一个被移出,其中一个存储器的输入口,另一个口是存储器的输出口。对于单片FIFO来说,主要有两种结构:触发导向结构和零导向传输结构。触发导向传输结构的FIFO是由寄存器阵列

构成的,零导向传输结构的FIFO是由具有读和写地址指针的双口RAM构成。

扩展资料:

FIFO存储器是系统的缓冲环节,如果没有FIFO存储器,整个系统就不可能正常工作,它主要有几方面的功能:

1、对连续的数据流进行缓存,防止在进机和存储操作时丢失数据;

2、数据集中起来进行进机和存储,可避免频繁的总线操作,减轻CPU的负担;

3、允许系统进行DMA操作,提高数据的传输速度。这是至关重要的一点,如果不采用DMA操作,数据传输将达不到传输要求,而且大大增加CPU的负担,无法同时完成数据的存储工作。

参考资料来源:百度百科-FIFO存储器

纯情的诺言
踏实的乌龟
2025-07-05 22:22:08
module FIFO(Wr_Clk,//write FIFO clock

nWr, //write FIFO signal

Din, //write FIFO data

Rd_Clk,//read FIFO clock

nRd, //read FIFO signal

Dout, //read FIFO data

Full, // 1 = FIFO full

Empty)// 1 = FIFO empty

input Wr_Clk, nWr, Rd_Clk, nRd

input [Bsize-1:0] Din

output [Bsize-1:0] Dout

output Full, Empty

reg Full, Empty

reg [Bsize-1:0] Buff [Dsize-1:0]

reg [Asize:0] Wr_Addr_Bin, Rd_Addr_Bin

reg [Asize:0] Sync_Wr_Addr0_Gray, Sync_Wr_Addr1_Gray, Sync_Wr_Addr2_Gray

reg [Asize:0] Sync_Rd_Addr0_Gray, Sync_Rd_Addr1_Gray, Sync_Rd_Addr2_Gray

wire [Asize-1:0] FIFO_Entry_Addr, FIFO_Exit_Addr

wire [Asize:0] Wr_NextAddr_Bin, Rd_NextAddr_Bin

wire [Asize:0] Wr_NextAddr_Gray, Rd_NextAddr_Gray

wire Asyn_Full, Asyn_Empty

parameter

Dsize = 256, Asize = 8,

Bsize = 8

initial

begin

Full = 0

Empty = 1

Wr_Addr_Bin = 0

Rd_Addr_Bin = 0

Sync_Wr_Addr0_Gray = 0

Sync_Wr_Addr1_Gray = 0

Sync_Wr_Addr2_Gray = 0

Sync_Rd_Addr0_Gray = 0

Sync_Rd_Addr1_Gray = 0

Sync_Rd_Addr2_Gray = 0

end

////////////////////FIFO数据的写入与输出//////////////////////////////////////

assign FIFO_Exit_Addr = Rd_Addr_Bin[Asize-1:0]

assign FIFO_Entry_Addr = Wr_Addr_Bin[Asize-1:0]

assign Dout = Buff[FIFO_Exit_Addr]

always @ (posedge Wr_Clk)

begin

if (~nWr &~Full) Buff[FIFO_Entry_Addr] <= Din

else Buff[FIFO_Entry_Addr] <= Buff[FIFO_Entry_Addr]

end

///////////////////FIFO读写的地址生成器///////////////////////////////////////

assign Wr_NextAddr_Bin = (~nWr&~Full) ?Wr_Addr_Bin[Asize:0]+1:Wr_Addr_Bin[Asize:0]

assign Rd_NextAddr_Bin = (~nRd&~Empty)?Rd_Addr_Bin[Asize:0]+1:Rd_Addr_Bin[Asize:0]

assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin >>1) ^ Wr_NextAddr_Bin

assign Rd_NextAddr_Gray = (Rd_NextAddr_Bin >>1) ^ Rd_NextAddr_Bin

always @ (posedge Wr_Clk)

begin

Wr_Addr_Bin<= Wr_NextAddr_Bin

Sync_Wr_Addr0_Gray <= Wr_NextAddr_Gray

end

always @ (posedge Rd_Clk)

begin

Rd_Addr_Bin<= Rd_NextAddr_Bin

Sync_Rd_Addr0_Gray <= Rd_NextAddr_Gray

end

///////////////////采用双锁存器把异步信号同步起来/////////////////////////////

always @ (posedge Wr_Clk)

begin

Sync_Rd_Addr2_Gray <= Sync_Rd_Addr1_Gray//读信号同步到写时钟

Sync_Rd_Addr1_Gray <= Sync_Rd_Addr0_Gray

end

always @ (posedge Rd_Clk)

begin

Sync_Wr_Addr2_Gray <= Sync_Wr_Addr1_Gray//写信号同步到读时钟

Sync_Wr_Addr1_Gray <= Sync_Wr_Addr0_Gray

end

/////////////////将产生的Full信号和Empty信号同步的各自的时钟域上//////////////

assign Asyn_Empty = (Rd_NextAddr_Gray==Sync_Wr_Addr2_Gray)

assign Asyn_Full = (Wr_NextAddr_Gray=={~Sync_Rd_Addr2_Gray[Asize:Asize-1],

Sync_Rd_Addr2_Gray[Asize-2:0]})

always @ (posedge Wr_Clk)

begin

Full <= Asyn_Full

end

always @ (posedge Rd_Clk)

begin

Empty <= Asyn_Empty

end

//////////////////////////////////////////////////////////////////////////////

endmodule

文静的大地
明亮的钢笔
2025-07-05 22:22:08
异步FIFO最小深度计算原理 如果数据流连续不断则FIFO深度无论多少,只要读写时钟不同源同频则都会丢数; FIFO用于缓冲块数据流,一般用在写快读慢时,遵循的规则如下: {FIFO深度 /(写入速率 - 读出速率)} = {FIFO...

清爽的柠檬
文艺的白昼
2025-07-05 22:22:08
FIFO是个队列,写操作和读操作是各自独立实现的。只要你设计的FIFO具有双端口数据总线,就可以实现同时读写。但如果只设计了一个数据总线端口,则读/写操作只能时分复用而无法同时进行了。