fifo的作用:缓存前级突发数据; 响应后级反压;给前级写反压;
fifo分类:
同步FIFO,读和写应用同一个时钟。它的作用一般是做交互数据的一个缓冲,也就是说它的主要作用就是一个buffer。
异步FIFO,读写应用不同的时钟,它有两个主要的作用,一个是实现数据在不同时钟域进行传递,另一个作用就是实现不同数据宽度的数据接口。
fifo上需要关注的参数:
- 宽度,用参数FIFO_data_size表示,也就是FIFO存储的数据宽度;
- 深度,用参数FIFO_addr_size表示,也就是地址的大小,也就是说能存储多少个数据;
- 满标志,full,当FIFO中的数据满了以后将不再能进行数据的写入;
- 空标志,empty,当FIFO为空的时候将不能进行数据的读出;
- 写地址,w_addr,由自动加一生成,将数据写入该地址;
- 读地址,r_addr,由自动加一生成,将该地址上的数据读出;
- afull_th,将满 阈值
- amty_th,将空阈值
- used_cnt,fifo内部剩余未读出数据
有关深度计算的场景:
1、fA>fB,且无空闲周期,即无间断读和写
写入时钟频率 fA = 80MHz;读取时钟频率 fB = 50MHz. 一次写入的突发长度120
读写操作不间断
Sol:
写入一个数据的时间为:1/(80MHz)=12.5ns
读取一个数据的时间为:1/(50MHz)=20ns
完成一次突发长度(120)的写时间为:120*12.5ns=1500ns
在这个突发时间1500ns内,可以读出的数据为:1500ns/20ns=75
在一次突发时间1500ns内写入120个数据,读出75个数据,剩余:120-75=45 ,剩余45个数据需要缓存到FIFO中,即FIFO的最小深度为45。
2、fA>fB,且在完成写和读都有delay,有延迟
此时与1所述相同
3、fA>fB,且在读和写有空闲周期
写入时钟频率 fA = 80MHz;读取时钟频率 fB = 50MHz. 一次写入的突发长度120。
每两次写入操作间隔1个写时钟周期,每两次读取操作间隔3个读时钟周期。
Sol:
要考虑闲置的cycle,因为会改变真正的写读时钟频率
相当于每两个时钟周期完成一次写操作,即相当于实际的写时钟频率fA'=40MHz,写入一个数据所需要的时间为:1/40MHz=25ns
每两次读取操作间隔3个读时钟周期,相当于每4个时钟周期完成一次读操作,即相当于实际的读时钟频率fB'=12.5MHz,读出一个数据所需的时间为:1/12.5MHz=80ns
在一次突发长度(120)内,写入的时间为:25ns*120= 3000ns
在这个突发时间3000ns内,可以读出的数据为:3000ns/80ns=37.5。
在一次突发时间3000ns内写入120个数据,读出37.5个数据,剩余:120-37.5=82.5 ≈83 (要向上取整,因为要保证FIFO的最小深度,避免溢出),剩余83个数据需要缓存到FIFO中,即FIFO的最小深度为83。
4、fA>fB,考虑写使能和读使能(占空比)
写入时钟频率 fA = 80MHz;读取时钟频率 fB = 50MHz. 一次写入的突发长度120。
写使能占空比=50%=1/2,读使能占空比=25%=1/4
Sol:
与3相同,同一个问题可能由不同问法提问
5、fA<fB,写时钟频率小于读时钟频率,且无空闲
写入时钟频率 fA = 30MHz;读取时钟频率 fB = 50MHz. 一次写入的突发长度120
写、读操作无间断
Sol:
因为读时钟频率比写时钟频率,数据一旦写入FIFO,就立刻被读出,所以FIFO深度最小为1。
6、fA<fB,写时钟频率小于读时钟频率,且有空闲
写入时钟频率 fA = 30MHz;读取时钟频率 fB = 50MHz. 一次写入的突发长度120
每两次写入操作间隔1个写时钟周期,每两次读取操作间隔3个读时钟周期。
Sol:
要考虑闲置的cycle,因为会改变真正的写读时钟频率
上述说法相当于,每两个写时钟周期完成一次写操作,即实际的写时钟频率fA'=15MHz,
完成一次写操作所需的时间为:1/15MHz=66.667ns
实际的读时钟频率fB'=12.5MHz,完成一次读操作所需的时间为:1/12.5MHz=80ns
在一次突发长度(120)内,写入的时间为:66.667ns*120= 8000ns
在这个突发时间8000ns内,可以读出的数据为:8000ns/80ns=100。
在一次突发时间8000ns内写入120个数据,读出100个数据,剩余:120-100=20 ,剩余20个数据需要缓存到FIFO中,即FIFO的最小深度为20。
7、fA=fB,写时钟频率等于读时钟频率,没有空闲
写入时钟频率 fA = 读取时钟频率 fB = 30MHz。一次写入的突发长度120。
写、读操作无间断
Sol:
1、假设读、写时钟无位差、则两个时钟同频、同相,是同步信号,故可以直接对接操作,无需FIFO
2、若读、写时钟存在相位差,则被写入的数据在一个时钟周期内会被读走,所以FIFO的最小深度为1即可
8、fA=fB,写时钟频率等于读时钟频率,且有空闲(或有占空比)
写入时钟频率 fA = 读取时钟频率 fB = 50MHz。一次写入的突发长度120。
每两次写入操作间隔1个时钟周期,每两次读取操作间隔3个时钟周期。
Sol:
每两次写入操作间隔1个写时钟周期,等于每两个写时钟周期才写入1个数据,即等价的写入时钟频率 fA'=25MHz,写入一个数据需要的时间:1/25MHz = 40ns
每两次读取操作间隔3个读时钟周期,等于每4个写时钟周期才读取1个数据,即等价的读取时钟频率 fB'=12.5MHz,读取一个数据需要的时间:1/12.5MHz = 80ns
写入120个数据,需要的时间:120 * 40ns = 4800ns
在写入全部数据所需的时间(4800ns)内,可以读取出的数据数:4800ns / 80ns = 60
所以一次突发,一共需要写入120数据,在这段时间内可以被读出60数据,剩下的数据就是需要使用FIFO来缓存,所以FIFO的最小深度为120 - 60 = 60
9、特定时间内读、写时钟频率固定
每100个时钟写入80个数据,剩余20个随机值(无效)
每10个时钟读出8个数据
一次写入的突发长度160
Sol:
这时候需要考虑多种情景, 因为每100个时钟内,仅写入80个数据,而这80个数据可能任意分布,所以160个数据的写入可能有以下几种情况:
考虑最坏的情况,写入时钟频率最快,读取时钟频率最慢,如图中写操作最快的是case-4,即连续的两次突发写入,又称为“背靠背”。
即写入160个数据用时160个时钟周期。
每个时钟读取的数据个数 = 8 / 10
所以160个时钟读出数据的个数为 160 *(8/10) = 128
剩下的没有读出,就存在FIFO中,则需要深度为:160 - 128 = 32
10、读写空闲周期不匹配
写入时钟20MHz
读出时钟40MHz
每1000个时钟周期写入500个数据
每4个时钟周期读出1个数据
读写数据位宽一致。
Sol:
考虑到“背靠背”的情况突发长度则为500 * 2 = 1000
则为每1000个时钟周期写入1000个数据
每4个周期,读取一个数据。
写一个数据需要的时间 = 1 / 20MHz = 50ns
写一个突发需要的时间 = 1000 * 50ns = 50000ns
读一个数据需要的时间 = 4 * (1 / 40MHz) = 100ns
每50000ns,120个数据被写入FIFO,但读一个数据需要100ns的时间
可以计算出,50000ns内读出可以多少个数据,50000 /100 = 500
剩下的没有读出,就存在FIFO中,则需要1000- 500 = 500
所以这种情况下,需要的FIFO最小深度为500
在SDRAM的应用中,我们通常使用的读写FIFO是突发长度的2倍,比如突发长度为256,那FIFO的深度设置为512,使得FIFO始终保持半满的状态。可以保证数据的传输。