李红科,王庆春,余顺园
(安康学院电子与信息工程学院,陕西安康 725000)
随着集成电路的飞速发展,超大规模集成电路芯片中一个完整系统包含多个时钟,不同时钟域控制下,数据在传输或存储之间会出现亚稳态现象。异步FIFO(Frist Input Frist Output)是解决跨时钟域数据传输和存储所引发亚稳态的有效方法之一。异步FIFO 在雷达、信号处理及多媒体技术等领域有着广泛的应用[1-3]。
FIFO是一种先进先出的双端口数据缓存器,和普通缓冲器区别在于FIFO没有外部地址线,优点是减少输入信号控制线,缺点是数据只能顺序写入、顺序读出[4-5]。图1给出了异步FIFO内部结构图,包括双端口RAM存储器、写控制器、读控制器、写地址指针同步到读时钟域(W2R 同步器)、读地址指针同步到写时钟域(R2W同步器)、读状态标志位和写状态标志位等部分[6-8]。
图1 异步FIFO内部结构图
写控制器模块:在写时钟和写使能信号作用下,产生写地址指针。
读控制器模块:在读时钟和读使能信号作用下,产生读地址指针。
R2W 同步器模块:读计数器同步到写时钟域,同步后计数器和写二进制计数器比较用于产生满标志位(full)信号条件。
W2R 同步器模块:写计数器同步到读时钟域,同步后计数器和读二进制计数器比较用于产生空标志位(empty)信号条件。
写状态标志位模块:写时钟控制下产生满(full)信号。
读状态标志位模块:读时钟控制下产生空(empty)信号。
异步FIFO 外部引脚如表1 所示。
表1 异步FIFO外部引脚
异步FIFO 设计过程中存在两个关键技术问题:1)亚稳态;2)空/满状态标志位判断及产生。在处理空/满标志位问题上,目前最常用的方案是增加一位读写指针附加位,当读写指针最高位相同其余位也相同时,认为读空,当读写指针最高位不相同其余位相同时,认为写满。
文中以宽度为8 位、深度为16 位的异步FIF0 为例,介绍亚稳态产生的原因以及降低亚稳态出现概率的方法,分析利用格雷码和同步转换来产生空/满标志位的方法。
在所有数字器件中,寄存器都定义了一个信号时序要求,满足时序要求的寄存器才能正确地在输入端获取数据、在输出端产生数据[9]。为确保操作可靠,输入数据在时钟沿之前必须稳定一段时间(建立时间),并且在时钟沿之后保持一段时间(保持时间),触发器经过一个特定时钟至输出延时后有效。如果一个数据信号在变化之前不满足触发器建立和保持时间要求,触发器输出可能会进入亚稳态。亚稳态触发器输出值会在高低电平之间徘徊不定,如图2 所示。
图2 亚稳态的产生示意图
虽然亚稳态在异步电路中无法避免,但是两级同步器和格雷码计数器可以降低亚稳态概率到可以接受的程度。
1)两级同步器
图3 中,clk1 和clk2 是异步时钟,FF1和FF2组成两级同步器[10-11],对不同时钟域的输入数据锁存两拍。一般情况下,两级锁存同步器是一级同步器出现亚稳态概率的平方,在大部分同步设计中,两级同步器可以大大降低亚稳态出现概率[12]。
图3 异步电路同步化处理
图4 中,当clk1 和clk2 上升沿很近时,data0 在变化时,此时clk2 上升沿采集到一个正在变化的数值,data1 是个不确定值,FF1触发器输出处于亚稳态,经过1 个时钟延时,data1 值趋于稳定,FF2在clk2 上升沿对data1 稳定值采样,输出data2 为确定值。虽然data1 在被clk2 上升沿采样时也有处于亚稳态的可能,但是这种概率很小,经过两级同步器能大大降低亚稳态概率[13-15]。两级同步器设计程序如下:
图4 两级同步器消除亚稳态
2)格雷码计数器
格雷码是一种误差最小化的可靠性编码,可以极大地减少由一个状态变化到下一个状态时电路产生的误差[11]。这种编码方式是两个相邻码之间只有一位变化,缺点是格雷码是无权码,不能直接用于计算、比较,需要转换为二进制代码计算。
亚稳态出现的原因是数据变化时建立和保持时间不够,数据地址经过二级同步器后,地址指针采用格雷码编码,地址指针一次只能变化一位,通过这种可以有效减少亚稳态出现概率。
但是格雷码指针不能直接比较产生空/满标志位,要产生空/满标志位,需要将格雷码读指针和写指针转换为相应二进制读指针和写指针进行比较。
格雷码转二进制码方法是格雷码最高位码等于二进制最高位码Bn-1=Gn-1,二进制次高位=二进制最高位与格雷码次高位异或,依次将n位格雷码转换为二进制码[11]。
为防止FIFO 误操作,设置空/满状态标志位,当空状态标志位empty=1时,FIFO 不能再读出数据。当满状态标志位full=1 时FIFO 不能再写入数据。因为FIF0位宽为8位,至少需要3位二进制数表示地址位。
读空条件:写指针(wr_pointer)=读指针(rd_pointer),如图5(a)所示。因为读指针和写指针变化是在不同时钟下完成,不能直接比较,必须转换到相同时钟下进行二进制比较,将读指针转换为写时钟域,当读指针等于写指针(w2r_bincnt==rd_bincnt)时,empty=1,FIFO 读空。
写满条件:对写满操作分两种情况讨论:1)一次性写满,当写时钟域下写二进制指针指向最后一个存储单元时,读时钟域下的二进制读指针指向第一存储单元时,(wr_pointer=15)&&(rd_pointer=0),full=1写满,如图5(b)所示;2)经过多次写满,一次只向FIFO写一部分数据,多次FIFO写满。例如第一次写入12个数据,第一次读出10 个数据,第二次再写入14 个数据时写满。当写时钟域下写指针指向第n个存储单元,写指针同步到读时钟域下的二进制写指针指向存在单元第n+1 个存储单元(wr_pointer=n)&&(rd_pointer=n+1)时,full=1,FIFO写满,如图5(c)所示。
图5 异步FIFO空/满状态产生逻辑图
整体设计包括:FIFO 存储器设计模块、写计数器同步读时钟域模块、读计数器同步写时钟域模块、空标志产生模块、满标志产生模块和格雷码计数器模块[16-19]。
FIFO 双端口RAM 模块设计代码如下:
写计数器同步读时钟域模块:用于产生空标志信号条件。其中rc1k、rst_n 和w2r_bincnt 分别是写时钟复位和写计数器转换到读时钟二进制计数器,设计代码如下:
读计数器同步写时钟域模块:用于产生满标志信号条件。其中wc1k 和rzw-bincnt 分别是写时钟和读计数器转换到写时钟二进制计数器,设计代码如下:
空标志产生模块:在读使能有效的情况下,读二进制计数器=写格雷码计数器同步并转换到读时钟域的写二进制计数器,empty=1,empty 信号产生具体代码如下:
满标志产生模块:读使能有效情况下,写二进制值计数器计数到最大值且同步到写时钟域读计数器计数最小值,或经同步后读计数=写计数器+1 时,full=1,full信号产生具体代码如下:
针对异步FIFO 出现满状态的两种情况进行两次仿真:1)第一种情况,FIFO 一次写满,在读时钟和读使能控制下依次向FIFO 写入十进制5~20,16 个无符号数,最后一个写操作结束,full=1,FIFO 写满。在写时钟和写使能控制下依次从FIFO 读出5~20,16个无符号数,最后一个读操作结束,empty=1,FIFO 读空,如图6 所示;2)第二种情况,FIFO 多次写满,在读时钟和读使能控制下依次向FIFO 写入十进制1~16,16个无符号数,最后一个写操作结束,full=1,FIFO 写满。在写时钟和写使能控制下依次从FIFO 读出1~10,10 个无符号数,再次向FIFO 写入0~9,10 个无符号数,full=1,FIFO 写满,最后把FIFO11~16,0~9,16个数据依次读出,empty=1,FIFO 读空,如图7 所示。
图6 第一种写满情况
图7 第二种写满情况
该文分析异步FIFO 内部结构,在此基础之上深入分析异步电路亚稳态产生的原因,针对亚稳态原因提出采用同步器和格雷码计数器的方法,可以有效降低亚稳态出现概率。针对传统的空/满标志位产生方法,提出一种新的空/满标志位产生方法。使读写满逻辑分两种情况讨论,分别对两种情况进行Modelsim 仿真验证,从仿真图上看,该设计正确,实现了预期目标。