FIFO篇
目录
说明
本文档根据 ALTERA 《SCFIFO and DCFIFO Megafunctions》一问整理而来。
笔者使用Quartus II 的版本及PC机操作系统版本为11.1 sp2 WIN7 32位。
本文档仅供学习、讨论使用,请勿用于商业用途。在使用该文档过程中有任何疑问请至笔者博客进行交流探讨。
文档版本 V1.0
笔者将随时可能对本教程中的内容进行更改,恕不事先通知。
摘要
ALTERA在LPM库中提供了参数可配置的单时钟FIFO(SCFIFO)和双时钟FIFO(DCFIFO)。FIFO主要应用在需要数据缓冲且数据符合先进先出规律的同步或异步场合。LPM中的FIFO包含以下几种:
1.SCFIFO:单时钟FIFO;
2.DCFIFO:双时钟FIFO,数据输入和输出的宽度相同;
3.DCFIFO_MIXED_WIDTHS:双时钟FIFO,输入输出数据位宽可以不同。
在本文中,如无特殊说明,DCFIFO通指上述两种双时钟FIFO。
第一章 FIFO配置全攻略
1.1如何配置自己需要的FIFO
配置FIFO的方法有两种,一种是通过QUARTUS II 中TOOLS下的MegaWizard Plug-In Manager 中选择FIFO参数编辑器来搭建自己需要的FIFO,这是自动生成FIFO的方法,另外如果你是大师级选手(对LPM-FIFO参数十分熟悉)还可以通过手动编写HDL来实现需要的FIFO。在此笔者建议大家,尤其是初学者使用自动方式来配置需要的FIFO,配置界面简洁明了十分容易上手。
1.2输入输出端口
下图中是SCFIFO和DCFIFO的框图,其中,SCFIFO中读写双方信号与时钟clock同步,DCFIFO读写双方信号分别与读写时钟同步。
表一中列出FIFO中各个IO的详细描述:
表一 端口描述
端口
类型
是否必选
描述
Clock
输入
是
上升沿触发时钟
Wrclk
输入
是
上升沿触发时钟,下列信号与之同步:
data
wrreq
Wrfull
Wrempty
wrusedw
Rdclk
输入
是
上升沿触发时钟,下列信号与之同步:
Q
Rdreq
Rdfull
Rdempty
Rdusedw
Data
输入
是
当wrreq有效时数据线上的数据通过DATA端口被写入FIFO中
Wrreq
输入
是
写请求信号,激发写入操作。
1.当full(对于SCFIFO)或wrfull(对于DCFIFO)有效时,不能激活wrreq信号,参数overflow_checking设置为ON,即在full状态下FIFO会自动无视写请求;
2.不能再aclr有效期间激活wrreq信号;
3. 使用Stratix 和Cyclone 系列器件(除了Stratix, Stratix GX,和Cyclone 系列以外)需要将write_aclr_synch参数选择位ON,确保符合限制条件。
Rdreq
输入
是
读请求信号,激发读出操作。
1.该信号的作用在正常模式下和在预读模式下的作用有很多不同(详情见后文);
2.当empty(对于SCFIFO)或rdempty(对于DCFIFO)有效时,不能激活rdreq信号,参数underflow_checking设置为ON,即在full状态下FIFO会自动无视读请求;
Sclr
Aclr
输入
非
清零端口,详情见后文
Q
输出
是
输出由读操作而从FIFO中读出的数据。
1.SCFIFO和DCFIFO中,输入输出数据的位宽必须相同;
2.DCFIFO_MIXED_WIDTHS型FIFO输入输出位宽可以不同,但是根据使用RAM的类型不同,输入输出位宽比率有不同的限制;
Full
Wrfull
Rdfull
输出
非
当该信号有效时,FIFO会被认为已经装满,此时不能再进行写操作;
Empty
Wrempty
Rdempty
输出
非
当该信号有效时,FIFO会被认为已经读空,此时不能再进行读操作;
Almost_full
输出
非
准装满信号,当usedw大于参数almost_full_value或相同时,该信号被激活,即是full信号被激活的预示;
Almost_empty
输出
否
准读空信号,当usedw小于参数almost_empty_value或相同时,该信号被激活,即是empty信号被激活的预示;
Usedw
Wrusedw
Rdusedw
输出
否
显示当前FIFO中数据存量。
表二中列出配置FIFO的各个参数详细说明:
表二 参数说明
参数
类型
是否必选
描述
Lpm_width
整数
是
对于SCFIFO和DCFIFO,该参数定义了data和q的位宽,对于DCFIFO_MIXED_WIDTHS该参数定义了data的宽度;
Lpm_width_r
整数
是
对于DCFIFO_MIXED_WIDTHS该参数定义了q的宽度;
Lpm_widthu
整数
是
对于SCFIFO,该参数定义了usedw端口的位宽,对于DCFIFO,定义了rdusedw和wrusedw的位宽,对于DCFIFO_MIXED_WIDTHS,定义了wrusedw端口的位宽;
Lpm_widthu_r
整数
是
对于DCFIFO_MIXED_WIDTHS,定义了rdusedw端口的位宽;
Lpm_numwords
整数
是
定义了FIFO深度,值至少为4,需要满足如下关系2^(LPM_WIDTHU-1) < LPM_NUMWORDS£
< 2^(LPM_WIDTHU)
.
Lpm_showhead
是
模式开关,选择正常模式或者是预读模式。
在正常模式下,rdreq有效时才读出数据;
在预读模式下,自动读出当前FIFO中第一个数据(FIFO不空时),当rdreq信号有效时,开始继续往后读取第二个数据;
Lpm_type
非
识别FIFO型号的参数,SCFIFO或者是DCFIFO
Maximize_speed
整数
非
空间或速度优化度参数,当值为0--5时为空间优化,6--10时为速度优化。
Overflow_checking
非
是否开启溢出检测,溢出时无视wrreq,值为NO或OFF,缺省值为ON;
Underflow_checking
非
是否开启下溢检测,下溢(读空)时无视rdreq,值为NO或OFF,缺省值为ON;
Delay_rdusedw
Delay_wrusedw
非
Add_usedw_msb_bit
非
用于增加rdusedw和wrusedw的位宽(1bit)防止FIFO满时翻转为0,该参数值为ON或OFF,缺省值为OFF,该参数仅针对某些系列器件有效。
Rdsync_delaypipe
Wrsync_delaypipe
整数
非
Use_eab
非
是否使用块RAM来构造FIFO,该参数值为ON或OFF,若设置为OFF则使用LE来构造FIFO;
Write_aclr_synch
非
是否将aclr设置为与wrclk同步,来避免wrreq和aclr之间的竞争,缺省值为OFF,仅在使用部分器件时有效;
Clocks_are_synchronized
非
Ram_block_type
非
Add_ram_output_register
非
选择是否寄存q输出数据;
Almost_full_value
整数
非
设置almost_full信号的阈值,当FIFO众数据量大于或等于该值时,激活almost_full信号;
Almost_empty_value
整数
非
设置almost_empty信号的阈值,当FIFO众数据量小于或等于该值时,激活almost_empty信号;
Allow_wrcycle_when_full
非
当SCFIFO已经满时,允许用户合并读写周期,缺省值为OFF,仅当overflow_checking参数设置ON时有效;
Intended_dvvice_family
非
设置使用器件型号,仅在功能仿真时使用。
1.3时序要求
1.如果设置了溢出保护电路或设置overflow_checking参数为ON,则在FIFO满时会自动无视wrreq信号,FIFO空时同理;
2.如果没有做上述两种措施中的任意一种,则当FIFO在装满时的同一时钟周期内不能对wrreq信号做出相应,即在此期间不能拉高wrreq,FIFO空时同理。
3.下面通过两幅时序图来具体说明:
1.4输出状态标记和潜伏期
对于DCFIFO,输出潜伏期如下图所示:
1.5避免亚稳态
1.6同步复位及异步复位的影响
在不同模式下,同步、异步复位的影响不同,SCFIFO支持同步或异步复位,DCFIFO支持异步复位,且该复位信号与写时钟同步。具体不同影响见表三(SCFIFO),表四(DCFIFO):
表三 同步或异步复位信号对SCFIFO 不同模式下的影响
模式
同步复位
异步复位
对状态位的影响
清除full,almost_full标志
激活empty,almost_empty标志
重置usedw标志;
触发点
时钟上升沿
随时
正常模式下对q输出的影响
如果Q没有寄存,则输出SCFIFO的首个数据,否则保持输出上一个数据;
保持输出上一个数据;
预读模式下对q输出的影响
如果Q没有寄存,则保持输出上一个数据持续一个时钟周期,随后在下一个时钟上升沿到来后输出SCFIFO的首个数据,若没有寄存则保持输出上一个数据;
如果Q没有寄存,则在下一个时钟上升沿到来后输出SCFIFO的首个数据,否则保持输出上一个数据;
表四 复位信号对DCFIFO 不同模式下的影响
模式
异步复位信号
与写时钟同步的异步复位信号
对状态位的影响
清除wrfull标志
在清除wrfull标志之前将之置1保持三个时钟上升沿;
清除rdfull标志
激活wrempty和rdempty标志
重置wrusedw和rdusedw标志;
生效触发点
随时
正常模式下对q输出的影响
如果q没有寄存,则输出保持不变,否则被清除;
预读模式下对q输出的影响
如果q没有寄存,则输出未知值,否则被清除。
1.7不同的输入输出位宽
DCFIFO_MIXED_WIDTHS这种类型的FIFO支持将输如输出数据设置为不同的位宽,在FIFO参数编辑器中可选择输入输出位宽比,这个比率必须满足一定要求,不同的输入输出时钟频率比和不同的所使用的RAM类型都限制了输入输出位宽比的选择。当选择不符合要求的位宽比时,是不能生成FIFO的。
下面举例说明,例如输入数据位宽16bit,输出数据位宽8bit,则输入输出时钟频率比应该成1:2的关系。同时在输入2个时钟周期即输入2个数据后,wrusedw标志值应该为2,此时rdusedw标志值应该为4,即在不再写入的前提下经过4个输出时钟周期后,FIFO被读空,激活empty标志。本例时序图如下图所示:
第二章 设计实例
2.1设计实例概要
在这个设计中,数据需要从ROM中转移到RAM中。ROM和RAM由不相关的时钟分别驱动,此时DCFIFO可以有效的处理异步时钟域的数据交换问题。系统框图如下:
2.2系统仿真分析
2.2.1写操作
2.2.1.1初始化
在系统上电后10ns前,reset信号被拉高,各个模块初始化,写控制器处于IDLE状态。在IDLE状态下写控制器把信号fifo_wrreq拉低,并从ROM地址00处请求数据。ROM被配置为输出不寄存模式,所以ROM数据直接传输至FIFO写输入端而无视reset信号。这样减少了数据潜伏时间,因为rom_out直接连接在fifo_in上,fifo_in是DCFIFO上的带寄存的输入口。
2.2.1.2写操作
如果在reset信号拉低后fifo_wrfull无效(低电平),则写控制器进入WRITE状态,写控制器将fifo_wrreq信号拉高,并进行写入操作,在WRITE状态下,rom_addr值保持不变,这样使得ROM中读出数据在被写入FIFO(下一个写时钟上升沿)之前稳定的保持至少一个写时钟周期。
2.2.1.3地址切换
当ROM中数据未被读完,即rom_addr小于ff时,WRITE状态后写控制器进入INCADR状态。在INCADR状态下,写控制器将fifo_wrreq拉低,并将rom_addr增加1。直到ROM中数据被取完。
2.2.2读操作
2.2.2.1初始化
在刚开始时,reset有效,此时fifo_rdempty信号被拉高。此时ram_addr=ff,这样在下一个状态时地址加一,这样可以确保RAM中地址00处恰好可以写入ROM地址00中的数据。
2.2.2.2写操作
在下一个时钟上升沿到来后,reset无效,fifo_rdempty被拉低,读控制器从IDLE状态进入INCADR状态,在INCADR状态下,读控制器将信号fifo_rdreq拉高,将数据从FIFO中读出并写入RAM。
2.2.2.3写入RAM
在INCADR状态后,读控制器进入WRITE状态,在WRITE状态下,ram_wren和ram_rden信号被拉高,使RAM从DCFIFO数据输出Q上接受数据并存入RAM中。
2.2.3当DCFIFO被写满时
2.2.3.1等待状态
当写控制器在INCADR状态下时,并且fifo_wrfull信号有效时,写控制器将在下一个写时钟上升沿到来后进入WAIT状态。在WAIT状态下,写控制器将保持rom_addr的值。如果fifo_wrfull信号持续有效,则写控制器继续保持WAIT状态,当fifo_wrfull无效时,在下一个写时钟上升沿到来后,写控制器将进入WRITE状态。
2.2.3.2WRITE状态
在WRITE状态下且当ROM尚未被读空时,写控制器拉高fifo_wrreq信号后,在下一个写时钟上升沿到来后,写控制器进入INCADR状态。
2.2.4完成ROM至DCFIFO的数据传递
2.2.4.1DONE状态
当写控制器处于WRITE状态下,且rom_addr=ff时,开始将ROM中最后一个数据写入DCFIFO中,在下一个写时钟上升沿到来后,写控制器进入DONE状态。
2.2.4.2ROM读取数据完毕后
在DONE状态下,写控制器将fifo_wrreq信号拉低,不在进入写操作状态。
2.2.5完成DCFIFO至RAM的数据传递
分析类似于2.2.4小结。