>
首页 » 技术文章 » 一种新型异步FIFO的设计

一种新型异步FIFO的设计

作者:西安电子科技大学微电子学院 王英力 庄奕琪  时间:2007-09-17 12:07  来源:电子设计应用

摘要:本文详细说明了一种新型异步FIFO的设计方法。该异步FIFO的宽度为8位,深度为16,支持深度为1的buffer模式。水位可编程。它具有四种FIFO状态,对于DMA和中断的支持非常有用。

关键词: 异步FIFO;水位;Verilog

引言

FIFO (先入先出队列)是一种在电子系统中得到广范应用的器件。FIFO可以分为同步FIFO和异步FIFO。同步FIFO只在一个时钟域里工作,比较简单。而异步FIFO是工作在两个时钟域里的FIFO。两个时钟域的频率和相位不同,在一个时钟域里向FIFO写数据,在另一个时钟域里把FIFO中的数据读走。本文设计的异步FIFO包含Buffer模式和水位可编程等新的想法,能够满足使用需求。

异步FIFO的主要特性

本文设计的异步FIFO的深度为16,宽度为8位。可以根据具体的应用而改变。

该异步FIFO有两种工作模式:FIFO模式和Buffer模式。当FIFO使能(fifo_en 置为1)时工作在FIFO模式,当FIFO不使能(fifo_en 置为0)时工作在Buffer模式。在FIFO模式时,FIFO的深度为16;在Buffer模式时,FIFO的深度为1。增加Buffer模式可以使该异步FIFO的应用范围更加广泛,使用时更加灵活。

该异步FIFO的水位是可编程的,支持1/8,1/4,1/2,3/4和7/8五种水位。水位的具体含义是:当FIFO中的数据量达到或超过水位时,FIFO的状态为OVERMARK。例如:在水位配置为1/2的情况下,当FIFO中的数据个数大于或等于8(8为水位与FIFO深度的乘积)时,FIFO的状态为OVERMARK。这样,DMA就可以根据FIFO的状态一次在FIFO中取走一定量的数据。对于支持DMA的外设,该项特性非常有用。
该异步FIFO在FIFO模式下可以输出四种FIFO状态,即FIFO_EMPTY、FIFO_NON_OVERMARK、FIFO_OVERMARK和FIFO_FULL。其中FIFO_NON_OVERMARK是当FIFO中的数据量低于水位时的FIFO状态。在Buffer模式下只有两种FIFO状态,即FIFO_EMPTY和FIFO_FULL。

异步FIFO的接口设计

异步FIFO的接口信号图如图1所示。wclk为写时钟,wreset_n为写时钟域里的复位信号,低电平有效。rclk为读时钟,rreset_n为读时钟域里的复位信号,低电平有效。write为写使能信号,高电平有效。read为读使能信号,高电平有效。empty和full为FIFO的空满状态。water_level为FIFO的水位。fifo_states为FIFO的状态。wdata和rdata分别为写数据线和读数据线。

异步FIFO模块的划分

本文采用自顶向下的方法,将设计划分为5个模块:DPRAM模块、WCTL模块,RCTL模块、W2R模块和R2W模块。

其中DPRAM模块、WCTL模块和R2W模块在写时钟(wclk)域里;RCTL模块和W2R模块在读时钟(rclk)域里。R2W模块和W2P模块为同步模块,R2W将读时钟域里的信号同步到写时钟域里,W2P将写时钟域里的信号同步到读时钟域里。

异步FIFO的关键部分设计

空满状态的判断

对于异步FIFO来说,空满状态的设计非常重要。要防止在FIFO已经满的情况下还对FIFO进行写操作,同时也要注意不要在 FIFO已经空的情况下还对其进行读操作。

采用将写指针和读指针相比较的方法可以更有效地判断FIFO的空满状态。写指针表示将要对FIFO进行写操作的写地址,读指针表示正在对FIFO进行读操作时的读地址。由于本FIFO的深度为16,所以可以将写指针和读指针设计为5位的位宽。其中低四位表示地址,最高位表示状态。

为了能更及时地显示FIFO的空和满状态,设定在WCTL模块进行满状态的判断,在RCTL模块进行空状态的判断。将RCTL模块输出的读指针rptr经R2W模块同步到写时钟域后为rptr_r2w,将rptr_r2w和WCTL模块中的写指针比较,若两个指针的低四位相同而最高位不同,则FIFO为满。将WCTL的读指针wptr经W2R模块同步到读时钟域后为wptr_w2r,将wptr_w2r和RCTL模块中的读指针比较,若两个指针相同,则FIFO为空。

rptr和wptr都用格雷码编码,由于相邻的两个格雷码之间只有一位不同,这样就可以避免在进行信号同步时,由于在同一个时钟沿有多个信号变化而引起的问题。

由于同步后的rptr_r2w比rptr有一定的延时,同步后的wptr_w2r比wptr也有一定的延时。因此,不会出现在FIFO已经满的情况下还对FIFO进行写操作和在 FIFO已经空的情况下还对其进行读操作的情况。

判断FIFO满的Verilog代码如下:
parameter ASIZE=4;  //addr size
always @(rptr_bin or waddr_tmp)
  begin
          if((rptr_bin[ASIZE-1:0]==waddr_tmp[ASIZE-1:0]) &&(rptr_bin[ASIZE]==(~waddr_tmp [ASIZE])))
              full_temp =1'b1 ; 
          else
              full_temp =1'b0 ;   
      end

Buffer模式下地址的控制

当fifo_en为低电平时,FIFO工作在Buffer模式下,当此时写使能有效且FIFO非满(读使能有效且FIFO非空)时,只改变写指针(或读指针)的最高位。这样就可以保证FIFO的深度为1,像一个8位的寄存器一样。

产生FIFO读地址的Verilog代码如下:
 always @(waddr_tmp or full_temp or fifo_en or write)
         begin
             if(full_temp==1'b0 && write==1'b1)
                begin
                    if(fifo_en==1'b1)  //in fifo mode
              waddr_next=waddr_ tmp+1'b1;
                    else             
//in buffer mode
               waddr_next=waddr_tmp+ 5'b1_0000;   
                end
            else
                waddr_next=waddr_tmp;   
        end

FIFO状态的确定

除了空和满状态外,在FIFO模式下还有FIFO_NON_OVERMARK和FIFO_OVERMARK两种状态。

判断这两种状态主要是根据FIFO中的数据量和FIFO的水位来判断的。FIFO中的数据量是通过写指针减去读指针得到的。先判断FIFO是否处于空或满的状态,然后再判断当FIFO中的数据量达到或超过水位时,FIFO的状态为FIFO_OVERMARK;当FIFO中的数据量低于水位时,FIFO的状态为FIFO_NON_OVERMARK。

判断FIFO状态的Verilog代码如下:
//compute the data number in fifo
parameter ASIZE=4;  //addr size
always @(rptr_bin or waddr_next)
      begin
          data_num=waddr_next[ ASIZE:0]+(~rptr_bin[ASIZE:0])+1'b1;
      end
  always @(water_level)
      begin
 case (water_level)
3'b000: data_water_level=4 'b0010;  //1/8
3'b001: data_water_level= 4'b0100;  //1/4
3'b010: data_water_level= 4'b1000;  //1/2
3'b011: data_water_level= 4'b1100;  //3/4
3'b100: data_water_level= 4'b1110;  //7/8
default:data_water_level=4'b1000;  //1/2
          endcase
      end
  //set the fifo_states
  always @(full_temp or empty_temp or data_num or data_water_level)
      begin
          if(empty_temp==1'b1)              fifo_states=`FIFO_EMPTY;
          else if(full_temp==1'b1)              fifo_states=`FIFO_FULL;
          else if(data_num >= data_water_level)                 fifo_states=`FIFO_OVERMARK;
else fifo_states=` FIFO_NON_OVERMARK;    
      end

同步模块的设计

设计中W2R模块和R2W模块为同步模块。把信号连续通过两个触发器可实现同步,这种同步方法十分简单,且准确性比较高。

仿真验证

本设计用Mentor Graphics公司的ModelSim进行仿真。当FIFO为空的时候,向FIFO连续写入16个数据,然后再将数据连续读出的仿真如图3所示。

结语

本文讨论了一种异步FIFO的设计方法,它支持Buffer模式,水位可以编程,有四种FIFO状态。经验证,该异步FIFO能够安全地实现数据的跨时钟域传递,有数据缓冲作用,可以应用到UART、SPI等通讯外设中。■

参考文献:
1. Clifford E.Cummings. Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Design. SNUG 2001 User Papers,March 2001
2. Clifford E.Cummings and Don Mills. Synchronous Resets?Asynchronous Resets?I am so confused! How will ever know which to use? SNUG 2002 User Papers,March 2002
3. Clifford E.Cummings and Peter Alfke. Simulation and Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer Comparisons,. SNUG 2002 User Papers,March 2002
4. Clifford E.Cummings. Synthesis and Scripting Techniques for Asynchronous Design. SNUG 2002 User Papers,March 2002

相关推荐

从TI“蝗虫战略”到雷军“芯片免费”

芯片  嵌入式系统  2013-11-07

嵌入式系统领域迎来创新与转型时代

嵌入式系统  通信  2013-05-30

VDC:物联网将改写嵌入式系统开发趋势

物联网  嵌入式系统  2013-05-14

飞思卡尔CEO:新战略初现成效 未来更关注中国市场

飞思卡尔  单片机  2013-04-28

飞思卡尔携手周立功单片机 共同拓展中国MCU市场

飞思卡尔  MCU  单片机  2012-12-19

英飞凌为提高XMC4000单片机生产率免费提供DAVE 3

英飞凌  单片机  2012-04-20
在线研讨会
焦点