摘 要:异步FIFO是一种先进先出电路,可以有效解决异步时钟之间的数据传递。通过分析异步FIFO设计中的难点,以降低电路中亚稳态出现的概率为主要目的,提出了一种格雷码计数器的技术,通过仿真验证,有效地实现了异步FIFO控制器的设计。该设计将大大提高工作频率和资源利用率。
关键词:异步FIFO;亚稳态;格雷码计数器
随着现代芯片设计规模的不断扩大,集成电路越来越复杂,一个系统中往往包含多个时钟,如何设计异步时钟之间的接口电路是多时钟领域的关键问题。异步FIFO(First In First Out)是一种先进先出电路,用来存储、缓冲在两个异步时钟之间的数据传输,使用异步FIFO可以在两个不同的时钟系统之间快速准确地传输实时数据,是用来解决异步时钟接口电路的一个有效方案。并且异步FIFO高速、可靠性好,在网络接口、图像处理等方面都得到了广泛的应用。
1异步FIFO控制器的设计
1.1 异步FIFO时钟域结构设计
FIFO主要由FIFO控制器和RAM两个部分组成。FIFO控制器最重要的功能就是产生RAM的读写地址以及相应的使能信号;产生FIFO的状态标志,包括空(Empty)、满(Full)、溢出(Underflow,Overflow)以及其他根据设计需要产生的状态标志。异步FIFO由两个时钟域构成:push clock domain(记为clk_push domain)和pop clock domain(记为clk_pop domain)。
所以异步FIFO可以划分为下列时钟域结构,如图1所示。
1.2 简单计数器实现读写地址输出结构设计
由时钟域结构可知,作为FIFO控制器,最基本的就是要根据外部的输入信号push和pop,产生对RAM访问的读写地址。FIFO控制器内首先要实现对RAM的读写地址输出,所以FIFO控制器内有一组基于clk_push domain的逻辑产生写地址:push_addr,和一组基于clk_pop domain的逻辑产生读地址:pop_addr。然后对地址信息采用二进制编码,每一次push操作,使push_addr增加1,即指向下一个push操作的RAM空间;每一次pop操作,使pop_addr增加1,即指向下一个pop操作的RAM空间。按照这种思路,异步FIFO控制器可进一步细化为如图2所示结构。
1.3 异步FIFO控制器设计中的关键问题
所谓异步是指读、写时钟是完全独立并且不一致的,或者不同频率,或者同频但不同相。读地址和空标志是由读时钟产生的,而写地址和满标志则由写时钟产生,当要产生FIFO的空、满标志时,必须进行读写地址的比较,地址线一般有多位,如果直接采样地址比较,就会存在问题。写地址的每一位在写时钟作用下,跳变会不一致,即产生毛刺,要过一段时间才能稳定。在未稳定期内,刚好读时钟进行采样写地址,这时就会出现误判断和逻辑错误从而导致了亚稳态的出现。一个好的FIFO设计的基本要求是:写满而不溢出,读空又不多读。
因而,异步FIFO设计主要存在两个关键问题:
(1)如何产生空、满等相应的控制信号;
(2)为了尽量降低电路中亚稳态出现的概率,如何同步从一个时钟域传送来的多位数据信号。
1.3.1 异步FIFO控制器空满标志产生
地址输出设计好后,接下来解决第一个关键问题,即异步FIFO的空满状态标志。
当pop_addr追赶push_addr,并且赶上,即pop_addr = push_addr时,FIFO为空,即置empty;当push_addr追赶pop_addr,并且赶上,即push_addr = pop_addr时,FIFO为满,即置full。
可以发现,不论是empty还是full,pop_addr均与push_addr相等,因而暂时无法区分到底是empty还是full。所以需要增加额外的逻辑加以区分。
由于异步信号在使用前需要使用两级触发器同步才能在另一个时钟域被使用,因而在clk_pop domain,需要两级触发器来同步push_cnt;在clk_push domain,也需要两级触发器来同步pop_cnt。
在这里可以增加almost_full和almost_empty标志判断empty和full:在计数器的复位值都必须为0,并且为二进制编码递增的前提下,当FIFO内数据少于某一预设值(低水线,low_waterlevel)时,置位almost_empty;当FIFO内数据多于某一预设值(高水线,high_waterlevel)时,置位almost_full。这时就很清楚,当almost_empty有效,并且pop_addr = push_addr时,FIFO为empty;当almost_full有效,并且pop_addr = push_addr时,FIFO为full。
此时,异步FIFO控制器可进一步细化为如图3所示结构。
1.3.2 亚稳态问题的存在及解决
在数字电路中,触发器需要满足setup/hold的时间要求。当一个信号被寄存器锁存时,如果信号与时钟之间不能满足这个要求,Q端的值是不确定的,并且在一个未知的时刻会固定到高电平或低电平,这个过程称为亚稳态。
亚稳态必然会发生在异步FIFO中, 因为在异步FIFO中,电路的外部输入和内部时钟没有任何时间关系,因此存在setup/hold冲突是必然的,同时,在电路内部的两个没有关系的时钟域之间的信号传递也会出现setup/hold冲突。
虽然亚稳态是不可避免的,但是通过对写地址/读地址用格雷码可以将其降低到一个能够接受的范围之内[1]。同步多个异步输入信号出现亚稳态的概率远远大于同步一个异步信号的概率,所以对多个触发器的输出所组成的写地址/读地址需要采用格雷码。由于格雷码每次只有一个数据位变化,因而采用格雷码可以有效地减少亚稳态的产生。
按照这种思路,异步FIFO控制器可以设计为计数器采用Gray Code编码,然后被另一个时钟域同步,同时计数器必须按照0、1、2、3递增的顺序计数。于是先将Gray Code转换为二进制,然后对二进制做加1运算,将计算结果再转换回Gray Code,然后被触发器锁存。所以,异步FIFO控制器的设计又可进一步细化为如图4所示结构。
现在一个异步FIFO控制器已经基本设计完成。在图上还剩overflow、underflow、we三个信号。在full时,对FIFO push就会产生overflow;在empty时,对FIFO pop就会产生underflow。特别值得注意的是,这时的push或pop都不应该使计数器继续翻转,full后对FIFO的push操作FIFO控制器也不能输出有效的对RAM的写使能信号we。这三个信号以及其他一些状态标志的具体实现可以根据实际应用进行设计。
2 用Modelsim仿真
在Modelsim SE上利用Verilog HDL对提出的方法进行了仿真,仿真波形如图5所示。
从仿真时序图知:
(1)复位后,读信号和写信号均不使能(均置1),由于存储单元没有数据,产生读空标志。
(2)将写信号使能(置0),写入的数据与设计输入的数据一致;将读信号使能,读出来的数据顺序和数值与写入的数据一致。
(3)将写信号置1,在一定的时钟下由预期设定的读地址加1与写地址相等时,有读空标志产生;接着将写信号使能,将读信号置1,在一定的时钟周期下由预期设定的写地址加1与读地址相等时,有写满标志产生。
(4)将读写时钟使能,数据的读写是正确的,由于写时钟比读时钟快,经过一定的时钟周期后,有写满标志产生;接下来,由于写满不能再写,故读时钟在读使能信号下读出数据时,写满信号变为0,接着写满信号1和0交替出现。
(5)系统复位后,一个8位rd_cnt计数器清0,在读使能和没有产生读空标志的条件下,在读时钟上升沿的到来,rd_cnt计数器加1,跟随着rd_addr读地址的变化,查看得知产生的读地址变化符合预期设计;同样,系统复位后,一个8 bit wr_cnt计数器清0,在写使能和没有产生写满标志的条件下,当写时钟上升沿的到来时,wr_cnt计数器加1,跟随着wr_addr写地址的变化,查看得知产生的写地址变化符合预期设计。
根据上述仿真波形分析,可以看出所设计的FIFO控制器,能满足需要完成的功能。
参考文献
[1] KANOOPOULOS,HALLENBECK J J. A First-In,Firstout memory for signal processing applications[J]. IEE Transactions on circuits and system,1986,CAS-33(05):556-558.
[2] 吴自信,张嗣忠.异步FIFO结构及FPGA设计[J]. 单片机及嵌入式系统应用,2003(8):24-26.
[3] CLIFFORD E. Simulation and synthesis techniques for asynchronous FIF0 design [J]. SNUG San Joes,2001(05).
[4] 罗昊. 一种异步FIFO的设计方法[J]. 电子技术应用,2004,30(8):70-71,74.
[5] 魏芳,刘志军,马克杰. 基于Verilog HDL的异步FIFO设计与实现[J]. 电子技术应用,2006,32(7):97-99.
[6] 杨青山,蔡敏. 基于多时钟域的异步FIFO设计[J]. 中国集成电路, 2007(9):36-39.