基于异步FIFO实现不同时钟域间数据传递的设计

合集下载

异步FIFO的实现方式

异步FIFO的实现方式

异步FIFO的实现方式实验目的本次实验介绍一种异步FIFO的实现方式。

使用FIFO存储器可以在两个不同时钟系统之间快速而方便的传输数据。

另外,在网络接口,图像处理等方面异步FIFO存储器也得到了广泛的应用。

因此,异步FIFO存储器具有较大的研究和应用价值。

异步FIFO的介绍和整体结构异步FIFO(First In First Out)存储器是指向FIFO缓冲器中写入数据的时钟域和从FIFO缓冲器中读取数据的时钟域是不同的,这两个时钟之间没有必然的因果关系。

异步FIFO是一种先进先出的电路,使用在异步时钟域数据接口的部分,用来存储、缓冲在两个异步时钟之间的数据传输。

在异步电路中,由于时钟之间周期和相位完全独立,所以数据的丢失概率不为零。

如何设计一个高可靠性、高速的异步FIFO存储器便成为一个难点。

异步FIFO的一般结构如图1所示,都是由一个读时钟域电路、一个写时钟域电路和一个双端口的RAM来构成的。

异步FIFO与同步FIFO所做的工作是相同的,都是在写信号有效时写数据到RAM中,在读信号有效时把数据从RAM中读出,所以对于中间部分的RAM 设计是比较简单的。

另外,读电路和写电路单独实现起来也是比较容易的,只需要按照同步FIFO的工作情况,如果没有写满或读空的状态时每写一个数据就把写地址加1,每读一个数据就把读地址减1。

设计难点在于两个时钟域的交叠部分:满、空状态的产生,这也是设计的重点。

图1 异步FIFO结构针对这个问题,先从对亚稳态的处理开始介绍亚稳态的处理一个触发器进入亚稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平上。

在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态、并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。

亚稳态发生的原因是由于在同步系统中,如果触发器的建立时间或保持时间不满足,就可能产生亚稳态,此时触发器输出端Q在亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态,逻辑误判有可能通过电路的特殊设计减轻危害(如本设计中将使用的Gray码计数器),而亚稳态的传播则扩大了故障面,难以处理。

跨时钟域之异步FIFO

跨时钟域之异步FIFO

跨时钟域之异步FIFOAsynchronous FIFO Design异步FIFO的读写指针写指针写指针指向当前将要写⼊数据的位置,复位之后,读写指针被置零。

执⾏写操作的时候,向写指针指向的存储区写⼊数据,之后写指针加1,指向接下来要被写⼊数据的位置。

On a FIFO-write operation, the memory location that is pointed to by the write pointer is written, and then the write pointer is incremented to point to the next location to be written.读指针:读指针指向当前要被读取数据的位置,复位时,读写指针被置零,FIFO为空读指针指向⼀个⽆效的数据(FIFO为空,empty信号有效——拉⾼)。

当第⼀个有效数据被写⼊FIFO之后,写指针增加,empty flag信号被拉低,且读指针⼀直指向FIFO第⼀FIFO空标志:当读写指针是相等的时候:分两种情况1.当读写指针执⾏复位操作的时候。

2.当读指针赶上写指针的时候,最后⼀笔数据从FIFO读出后FIFO为空FIFO满标志:读写指针相等,当FIFO⾥⾯的写指针写满⼀圈之后⼜转回到和读指针同样的位置。

有个问题,读写指针相等的时候怎么判断FIFO是empty还是full?设计的时候增加⼀位bit去辅助判断FIFO是空还是满。

当写指针超过FIFO的最⼤寻址范围时,写指针将使辅助位zhi⾼,其余位为0.FIFO满的时候:读写指针的低位(n-1位bit)相等,⾼位(第n位bit)不同。

FIFO空的时候,读写指针的低位和⾼位都相等。

(针对⼆进制)但是⼆进制FIFO指针综合电路复杂,⼀般采⽤**格雷码**,⽂章中采⽤⼆进制转换格雷码的⽅法,判断FIFO的空满标志4位⼆进制格雷码,有效地址位为三位。

⼆进制转换为格雷码的算法:rgraynext = (rbinnext>>1) ^ rbinnext;1.顶层模块fifo:例化各个⼦模块//顶层模块实例化各个⼦模块module fifo#(parameter DSIZE = 8, //读写数据位宽均设置为8位parameter ASIZE = 4 // 存储地址位宽设置)(output [DSIZE-1:0] rdata,output wfull,output rempty,input [DSIZE-1:0] wdata,input winc, wclk, wrst_n,input rinc, rclk, rrst_n);wire [ASIZE-1:0] waddr, raddr;wire [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;// 内部线⽹// synchronize the read pointer into the write-clock domainsync_r2w sync_r2w(.wq2_rptr (wq2_rptr),.rptr (rptr ),.wclk (wclk ),.wrst_n (wrst_n ));// synchronize the write pointer into the read-clock domainsync_w2r sync_w2r(.rq2_wptr(rq2_wptr),.wptr(wptr),.rclk(rclk),.rrst_n(rrst_n));//this is the FIFO memory buffer that is accessed by both the write and read clock domains.//This buffer is most likely an instantiated, synchronous dual-port RAM.//Other memory styles can be adapted to function as the FIFO buffer.fifomem#(DSIZE, ASIZE)fifomem(.rdata(rdata),.wdata(wdata),.waddr(waddr),.raddr(raddr),.wclken(winc),.wfull(wfull),.wclk(wclk));//this module is completely synchronous to the read-clock domain and contains the FIFO read pointer and empty-flag logic.rptr_empty#(ASIZE)rptr_empty(.rempty(rempty),.raddr(raddr),.rptr(rptr),.rq2_wptr(rq2_wptr),.rinc(rinc),.rclk(rclk),.rrst_n(rrst_n));//this module is completely synchronous to the write-clock domain and contains the FIFO write pointer and full-flag logicwptr_full#(ASIZE)wptr_full(.wfull(wfull),.waddr(waddr),.wptr(wptr),.wq2_rptr(wq2_rptr),.winc(winc),.wclk(wclk),.wrst_n(wrst_n));endmodule2.时钟域同步模块sync_r2w:读指针同步到写时钟域wclk// 采⽤两级寄存器同步读指针到写时钟域module sync_r2w#(parameter ADDRSIZE = 4)(output reg [ADDRSIZE:0] wq2_rptr, //读指针同步到写时钟域input [ADDRSIZE:0] rptr, // 格雷码形式的读指针,格雷码的好处后⾯会细说input wclk, wrst_n);reg [ADDRSIZE:0] wq1_rptr;always @(posedge wclk or negedge wrst_n)if (!wrst_n) beginwq1_rptr <= 0;wq2_rptr <= 0;endelse beginwq1_rptr<= rptr;wq2_rptr<=wq1_rptr;endendmodule原理图3.时钟域同步模块sync_w2r:写指针同步到读时钟域rclk//采⽤两级寄存器同步写指针到读时钟域module sync_w2r#(parameter ADDRSIZE = 4)(output reg [ADDRSIZE:0] rq2_wptr, //写指针同步到读时钟域input [ADDRSIZE:0] wptr, //格雷码形式的写指针input rclk, rrst_n);reg [ADDRSIZE:0] rq1_wptr;always @(posedge rclk or negedge rrst_n)if (!rrst_n)beginrq1_wptr <= 0;rq2_wptr <= 0;endelse beginrq1_wptr <= wptr;rq2_wptr <= rq1_wptr;endendmoduleRTL原理图4.存储模块//存储模块module fifomem#(parameter DATASIZE = 8, // Memory data word widthparameter ADDRSIZE = 4 // 深度为8即地址为3位即可,这⾥多定义⼀位的原因是⽤来判断是空还是满,详细在后⽂讲到) // Number of mem address bits(output [DATASIZE-1:0] rdata,input [DATASIZE-1:0] wdata,input [ADDRSIZE-1:0] waddr, raddr,input wclken, wfull, wclk);////////////////////////////////这部分没⽤到,可以单独写⼀个模块来调⽤//////////////`ifdef RAM //可以调⽤⼀个RAM IP核// instantiation of a vendor's dual-port RAMmy_ram mem(.dout(rdata),.din(wdata),.waddr(waddr),.raddr(raddr),.wclken(wclken),.wclken_n(wfull),.clk(wclk));//////////////////////////这部分没⽤到,可以单独写⼀个模块来调⽤//////////////////`else //⽤数组⽣成存储体// RTL Verilog memory modellocalparam DEPTH = 1<<ADDRSIZE; // 左移相当于乘法,2^4 将1左移4位reg [DATASIZE-1:0] mem [0:DEPTH-1]; //⽣成2^4个位宽位8的数组assign rdata = mem[raddr];always @(posedge wclk) //当写使能有效且还未写满的时候将数据写⼊存储实体中,注意这⾥是与wclk同步的if (wclken && !wfull)mem[waddr] <= wdata;`endifendmodule原理图5. rptr_empty模块:产⽣rempty和raddr信号//产⽣empty信号和raddar信号的模块module rptr_empty#(parameter ADDRSIZE = 4)(output reg rempty,output [ADDRSIZE-1:0] raddr, //⼆进制形式的读指针output reg [ADDRSIZE :0] rptr, //格雷码形式的读指针input [ADDRSIZE :0] rq2_wptr, //同步后的写指针同步到读时钟域input rinc, rclk, rrst_n);reg [ADDRSIZE:0] rbin;wire [ADDRSIZE:0] rgraynext, rbinnext;// GRAYSTYLE2 pointer//将⼆进制的读指针与格雷码进制的读指针同步always @(posedge rclk or negedge rrst_n)if (!rrst_n) beginrbin <= 0;rptr <= 0;endelse beginrbin<=rbinnext; //直接作为存储实体的地址rptr<=rgraynext;//输出到 sync_r2w.v模块,被同步到 wrclk 时钟域end// Memory read-address pointer (okay to use binary to address memory)assign raddr = rbin[ADDRSIZE-1:0]; //直接作为存储实体的地址,⽐如连接到RAM存储实体的读地址端。

异步fifo的工作原理

异步fifo的工作原理

异步fifo的工作原理今天咱们来唠唠异步FIFO这个超有趣的东西哦。

你可以把异步FIFO想象成一个特别的小仓库,这个小仓库是用来存放数据的呢。

不过它可有点特别,和咱们平常那种规规矩矩同步的仓库不太一样。

异步FIFO主要是在不同时钟域之间工作的。

就好比啊,有两个世界,一个世界的节奏快,另一个世界的节奏慢,异步FIFO就在这两个节奏不一样的世界之间搭起了一座数据的桥梁。

那它怎么存数据呢?当有数据要进来的时候,就像是有人要往这个小仓库里送货。

在写端口这边,有一个写指针,这个写指针就像一个小向导,它告诉大家数据应该放在仓库的哪个位置。

每次有新的数据要存进来,写指针就会指向下一个空闲的地方。

就像我们在图书馆书架上找空位放书一样,写指针就是那个帮我们找空位的小助手。

再说说读这边吧。

读端口有个读指针,这个读指针就负责从仓库里取数据。

它就像一个小管家,知道哪些数据已经被取走了,哪些还在仓库里等着被取。

读指针也是一步一步地移动,每次取走一个数据,就会指向下一个要取的数据的位置。

这里面有个超关键的东西,就是空满标志的判断。

你想啊,如果仓库满了,还往里塞东西,那不就乱套了嘛;或者仓库都空了,还在傻乎乎地去取数据,那也不行呀。

对于空满标志的判断呢,其实有点小巧妙。

因为是异步的,时钟不一样,所以不能简单地用一个计数器来判断。

一般会采用一些特殊的编码方式,像是格雷码。

为啥用格雷码呢?这就像是给这个小仓库的货物管理上了一道保险。

格雷码的好处就是相邻的码值只有一位不同。

这样在不同时钟域转换的时候,就不容易出错啦。

比如说,写指针和读指针在判断满的时候,不是简单地看数字大小哦。

因为时钟不一样,数字可能会乱套。

用格雷码就不一样啦,它能很准确地判断出是不是真的满了。

就好像是两个人在不同的节奏下数数,但是通过一种特殊的规则,能准确知道什么时候仓库满了。

还有哦,异步FIFO的深度也是个很重要的概念。

深度就像是这个小仓库的大小。

如果数据来的太快,而读的速度又跟不上,那仓库就得大一点,不然就容易满了溢出来。

异步FIFO设计

异步FIFO设计

异步FIFO设计2011.6.22摘要本文采用格雷码设计了一个异步FIFO,经过DC综合的结果如下:时钟频率:1.1GHz面积: 10744.447um2功耗: 7.791mw目录1. 异步FIFO的设计 (22)1.1 异步FIFO简介 (22)1.2 FIFO的参数 (22)1.3 FIFO的设计原理 (22)1.4 FIFO的设计模块 (66)1.5 用modelsim仿真FIFO (1111)1.6 用DC对FIFO进行综合 (1313)2.参考文献 (1515)1. 异步FIFO的设计1.1 异步FIFO简介FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。

同步FIFO是指读时钟和写时钟为同一个时钟。

在时钟沿来临时同时发生读写操作。

异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

异步FIFO(Asynchronous FIFO),一般用于不同时钟域之间的数据传输,比如FIFO的一端连接频率较低的AD数据采样信号,另一端与计算机的频率较高的PCI总线相连。

另外,对于不同宽度的数据接口也可以用AFIFO,例如单片机为8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用AFIFO来达到数据匹配的目的。

由于实际中,异步FIFO比较常见。

为了便于描述,在后面的章节中将异步FIFO简称为FIFO.1.2 FIFO的参数FIFO的宽度:进行一次读写操作的数据的位宽。

FIFO的深度:双口存储器中能容纳的数据的总数。

满标志: FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出。

基于异步FIFO实现不同时钟域间数据传递的设计

基于异步FIFO实现不同时钟域间数据传递的设计

基于异步FIFO实现不同时钟域间数据传递的设计[ 2006-12-18 13:31:00 | By: 夏虫 ]推荐摘要:数据流在不同时钟域间的传递一直是集成电路芯片设计中的一个重点问题。

本文通过采用异步FIFO的方式给出了这个问题的一种解决方法,并采用Verilog 硬件描述语言通过前仿真和逻辑综合完成设计。

关键词:异步FIFO;时钟域;Verilog引言当今集成电路设计的主导思想之一就是设计同步化,即对所有时钟控制器件(如触发器、RAM等)都采用同一个时钟来控制。

但在实际的应用系统中,实现完全同步化的设计非常困难,很多情况下不可避免地要完成数据在不同时钟域间的传递(如高速模块和低速模块之间的数据交换)。

这时,如何保持系统的稳定,顺利完成数据的传输就成为一个重要的问题,这也是异步电路设计中最为棘手的问题。

通常的做法是采用对每位信号加同步器或增加握手信号来解决这一问题,但这样会增加系统的复杂度且影响传输速度。

本文的做法是在两个时钟域的交界处设计一个异步FIFO,通过它来实现数据流的传输。

由发送时钟域将数据写入,接收时钟域将数据取出,在数据传输的同时实现了数据的缓存,因此是一种较理想的方法。

不同时钟域间数据传递的问题及其解决方法不同时钟域间数据传递的最重要问题就是亚稳态问题。

当数据信号通过两个时钟域的交界处时,将会分别由这两个时钟来控制信号的值。

此时如果两时钟信号的敏感沿非常接近并超过了允许的额度,则将出现数据信号的不稳定,即电路陷入亚稳态,也称为同步失败。

亚稳态是在两时钟敏感沿靠得很近、第二级时钟敏感沿到来时其输入数据不稳时发生,可将其视为仅仅是第二级触发器输入信号不稳定所导致的结果。

只要使输入信号稳定,就能解决亚稳态问题。

针对如上所述亚稳态的特点,可设计一个同步器来保证数据的稳定传输以解决这个问题。

其原理在于使信号在新的时钟域中先稳定下来再进入相关的逻辑,以保证信号与新的时钟同步。

本设计在时钟域的接口处就采用此法。

基于多时钟域的异步FIFO设计

基于多时钟域的异步FIFO设计

基于多时钟域的异步FIFO设计摘要:在大规模集成电路设计中,一个系统包含了很多不相关的时钟信号,当其目标域时钟与源域时钟不同时,如何在这些不同域之间传递数据成为了一个重要问题。

为了解决这个问题,我们可以用一种异步FIFO(先进先出)存储器来实现。

本文介绍了一种利用格雷码指针实现在多时钟域传递数据的FIFO设计。

关键词:FIFO,多时钟域,异步,格雷码,亚稳态,同步装置1、引言随着计算机、多媒体和数据通信技术的高速发展,数字图像、语音等数据传输技术近年来得到了极大的重视和长足的发展,并得到了广泛的应用。

如何保障这些语音、图像等数据传输的准确性、及时性?如何高效率、高速度地传输这些数据?这些都是当今信息领域的科研人员所必须解决的问题。

而往往在这些数据传输系统中,又会遇到不同系统接口间数据传输的问题。

通常在两个相连接的不同电路系统之间,因为每个系统的数据传输速度不同,在系统的接口部分就会出现数据输入速度和输出速度不同,也就是会发生数据传输速率不匹配的问题。

这种情况往往会让传输的数据产生复写或者丢失,降低数据的传输速率,同时也因为数据复写、丢失和无效数据的读入,将会产生数据出错,因此需要在不同系统的接口处设计数据传输单元来实现数据的高速高效传输。

在现代的系统设计中,为了提高系统的性能,设计者对数据的传输率、数据的传输量,对系统各部分之间的接口部分不同的数据输入和接收传输率的匹配有越来越高的要求,而FIFO存储器以其合理的价格、使用的方便灵活性以及上述的对速度匹配的应用而成为解决这类问题的理想途径,因此FIFO存储器在计算机、多媒体和数据通信领域都有着广泛的应用,因此对FIFO 的研究与设计应用具有理论上和实际应用上的双重意义。

2、FIFO的功能描述FIFO 是数据传输系统中极其重要的一环,特别是在两个处在不同时钟域的系统接口部分,FIFO 的合理设计,不但能使接口处数据传输的输入输出速率进行有效的匹配,不使数据发生复写、丢失和读入无效数据的情况,而且还会有效地提高系统中数据的传输效率,FIFO 存储器主要分为基于移位寄存器型和基于RAM 型,而RAM 型又有单口RAM和双口RAM 之分,目前来说,用的较为广泛的是基于双端口RAM的FIFO。

基于FPGA的异步FIFO设计与实现

基于FPGA的异步FIFO设计与实现

基于FPGA的异步FIFO设计与实现王伟国;张振东【摘要】随着现代数字电路系统密度和规模的不断扩大,一个系统中通常会包含多个时钟,因此不同时钟之间的数据传输成为亟待解决的问题.而一种可靠易行的解决方案就是异步FIFO.异步FIFO需要非常严格的多时钟技术,难以作出正确的设计合成和分析.本文提出了一种利用格雷码作为读写地址计数器的异步FIFO的设计方法,有效的避免了数据在不同时钟时间传输时遇到的亚稳态问题.并给出了综合仿真结果.%With the expanding of the density and scale of modern digital circuitry,a system will contain multiple clock.Therefore,the transfer of data between different clock becomes a serious problem needs to be solved.A reliable and feasible solution is asynchronous FIFO.Asynchronous FIFO require very strict clock technology,it is difficult to make the correct design of synthesis and analysis.This paper presents a design method of asynchronous FIFO which based on read/write counter in terms of gray code.This method effectively avoid the metastable state in the data transmission between different clock and given a comprehensive simulation results.【期刊名称】《聊城大学学报(自然科学版)》【年(卷),期】2012(025)003【总页数】6页(P79-84)【关键词】多时钟;异步fifo;verilog;HDL;格雷码【作者】王伟国;张振东【作者单位】中国科学院长春光学精密机械与物理研究所,吉林长春130033;中国科学院长春光学精密机械与物理研究所,吉林长春130033/中国科学院研究生院,北京100039【正文语种】中文【中图分类】TN4330 引言随着现代数字电路系统的实时数据处理能力的不断提高,逻辑电路的复杂程度和内核处理器的运算速度也快速增长,在使得一些复杂算法得以实现的同时也加剧了快速CPU与慢速外设之间的冲突.异步FIFO大量数据缓存的能力成功的解决了这一问题,但专用的高速异步FIFO芯片价格昂贵,且容量受限,随着现场可编程逻辑器件容量和速度的不断提高,利用现场可编程逻辑器件设计异步FIFO成为可行的方法.本文首先讨论了异步FIFO设计中经常出现的亚稳态问题和二进制计数器多位同时改变的问题,并给出解决办法,然后讨论了两种格雷码计数器的形式并作出比较,最后给出一种以格雷码为读写地址计数器的异步FIFO的设计方法和在设计异步FIFO时必须要注意的细节.1 多时钟电路中的亚稳态问题在一个时序电路中,合理的建立时间和保持时间是触发器正常工作的前提条件.对于下降沿触发的触发器而言,下降沿触发之前输入数据持续的最短时间是建立时间(setup time),下降沿触发之后输入数据持续的最短时间是保持时间(hold time).当电路时序不能满足setup time/hold time的要求时,系统时序就会出现混乱.在异步时序电路中,不同时钟之间是不存在任何关系的,必然会产生建立时间和保持时间冲突.解决系统时序问题常用双锁存器法如下图1所示,即在不同时钟之间传输数据时连续锁存两次.但是这种方法只是保证了电平的稳定,而在实际的系统中还需要FIFO作为不同时钟之间传输多位数据的接口.图1 避免亚稳态出现的双锁存器法2 异步FIFO指针对于同步FIFO来说,使用一个计数器计算读出和写入到FIFO缓存器中的数据量,计数器在只有写没读是递增,只读没写是递减,既读又写和没读也没写时保持不变.当计数器到达设定值时FIFO满信号置位,为零时空信号置位.在异步FIFO中,由于这种计算数据个数增减的计数器会被两个不同的时钟控制,因此这种计数器不能使用.所以,为了决定FIFO“空”和“满”状态,读指针和写指针必须相互比较.设计FIFO最主要的困难是生成FIFO指针和找到一个决定FIFO“空”和“满”状态的可靠方法.在FIFO设计中,读指针和写指针总是指向下一个要读和写的地址空间.当读或写操作完成后指针自动递增,当FIFO是空时读指针和写指针相等,当FIFO满时读指针和写指针也是相等.一种解决的方法是增加一个多余的MSB位来区分两种状态,当写指针递增超过地址范围时,写指针会递增MSB位,其他位清零,读指针同样也是.当读指针和写指针的MSB位不同时,意味着写指针比读指针多走了一圈,当MSB位相同时意味着走的圈数相等(如图2所示)图2 增加多余MSB后区分FIFO空和FIFO满的方法示意图当FIFO存储缓冲区需要(n-1)位地址时,地址指针用n位,当指针相等(包括MSB位)时空标志置位,当指针低(n-1)位相等且MSB位不等时满标志置位.2.1 二进制FIFO指针的情况二进制地址计数量会有多个位同时变化,因此在把二进制量在不同时钟域之间同步时会出现问题.一个解决的方法是取样并把周期计数量寄存在一个保持寄存器中,并发出一个ready信号,新时钟域收到信号并发出确认信号,这样变化的计数量就安全的传送到新时钟域.用这种方法不会产生上溢和下溢,因为当读指针递增到与写指针相等时,空信号置位,取样的写指针不反映当前写指针的值,而是小于当前值,故永远不能产生下溢,满信号也是如此.最常用的解决方法是用格雷码计数器,格雷码在每个时钟只有一位变换可以极大的减少在同步计数时错误的发生.3 格雷码计数器设计格雷码计数器的方法有很多,这里介绍二种简单直接的方法.下面详细介绍两种方法.3.1 格雷码计数器中的问题为了更好的理解把n-bit计数器转换成(n-1)-bit计数器时出现的问题,先考虑一下一个双重4-bit和3-bit格雷码计数器的例子如图3.图3 4-bit格雷码计数器示例及转换成3-bit格雷码时出现的问题在4-bit计数器中除了MSB位其余位关于中间对称,我们把2nd MSB位反相后,上半部分与下半部分的LSBs便相等.但是经过反相操作后整体便不是格雷码了,例如15(1100)到0(0000)的转变过程有两个bits变化,在下面的第一种格雷码计数器中会有解决方法.3.2 第一种格雷码计数器图4是第一种计数器的框图并是双重格雷码计数器中两个bits同时跳变的解决方法.其中假设输出寄存器的值是格雷码(ptr),此格雷码被输出到格雷码到二进制的转换器中,然后通过一个有条件递增的加法器并输出下一个格雷码值(gnext),连接到输出寄存器的输入端,如框图上半部分所示.(n-1)-bit格雷码简单地通过n-bit格雷码的2个MSBs的异或操作产生,(n-2)个LSBs不变.图4 第一种格雷码计数器示意图及其如何避免了两位同时跳变问题3.3 第二种格雷码计数器此种风格的格雷计数器(如图5所示)用了两组寄存器避免了把格雷码转换成二进制数的步骤.而且第二组寄存器也可以直接用来寻址FIFO存储器.n-bit格雷码指针仍然需要同步到不同的时钟域中.二进制指针可以更容易的通过计算产生“几乎满”和“几乎空”信号.因此在本论文的设计中用此种风格的格雷码计数器.图5 第二种格雷码计数器工作示意图4 总体设计及“空”和“满”信号的产生总体设计如图6所示,本设计方案共有四个模块,双口RAM模块,读控制模块,写控制模块,格雷码同步模块.写控制模块主要是当写使能信号有效且写满信号无效时产生写地址并实行地址递增功能,读控制模块实现相似功能,双口RAM模块用来使缓冲数据其读写动作可同时进行.4.1 “空”和“满”信号的产生“空”信号的产生比较简单,只需同步到读时钟域的写地址格雷码与n-bit的读指针的格雷码完全相等即可代码如下图6 异步FIFO总体设计框图及其信号说明但是,“满”信号的产生就没那么容易,简单地用n-bit格雷码作比较判断“满”信号是不可靠的.因为格雷码除了MSB位外是对称的如图3所示.在图3中假如写指针和读指针都指向地址7,此时写指针递增一次后,写指针指向地址8,读指针和写指针相比较,除了MSB位不同外其余各位均相等,满信号此时有效,但这是不符合实际情况的,错误的.这也是为什么在图4中应用双重n-bit格雷码计数器的一个原因.正确判断满信号的条件是:读写指针的n-bit格雷码的前两个MSBs都不相等,其余的写指针和同步读针相等.代码如下4.2 不同时钟速度因为异步FIFO被两个不同的时钟控制,很明显两个时钟运行在不同的速度下.当把较快的时钟同步到较慢的时钟时,会有一些计数值被跳过.当被同步的格雷码递增两次只被取样一次时也不会出现亚稳态问题,因为亚稳态出现在同步时钟上升沿附近有多位同时跳变时,而在两个同步时钟沿之间有格雷码跳变两次,第一次跳变距离同步时钟条边沿较远,只有第二次跳变在同步时钟沿附近,故不会产生亚稳态.当较快的格雷码计数器在较慢时钟沿之间递增多于一次,不会出现已经溢出却没有检测到的现象,因为同步到写时钟域的读指针滞后于当前的读指针,而写指针只会小于或等于同步读指针,故不会出现溢出.5 设计仿真及总结本设计采用Xilinx公司Spartan3A系列的XC3S1400A,封装时PG484,速度是-4,仿真器是ISE Simulator(VHDL/Verilog),硬件描述语言是Verilog,开发工具是ISE.最后对电路进行时序分析,结果为该FIFO运行速度可达到90.63MHz.wclk、rclk时钟周期分别为:75MHz、80MHz.先向FIFO中写入18个数据,当第16个数据被读入后wfull立即被置位如下图7.图7 写满仿真结果同时向FIFO中写入和读出数据,由于wptr要经过两个读周期才能同步到读时钟域,故在waddr递增后的第二个rclk的上升沿rempty才清零如下图8所示.本文对异步FIFO的结构和重要时序问题给予了详细的阐述,并得到了可靠的仿真结果.在高速数据采集系统中,采用高性能FPGA作为数据预处理和高速异步FIFO 作为数据采集缓存的应用都十分广泛.把FIFO集成在FPGA中简化了电路设计的复杂程度,增加了电路的集成化程度和可靠性,是未来高速数据采集系统的重要发展方向.图8 同时写入读出时的仿真结果参考文献【相关文献】[1] Clifford E.Cummings,Synthesis and Scrip ting Techniques for De signing Multi-Asynchronous Clock Designs[A].SNUG-2001,2001(3):2-8.[2]吴自信,张嗣忠.异步FIFO结构及FPGA设计[J].单片机及嵌入式系统应用,2000,22(3):1.[3]赵雅兴.FPGA原理、设计与应用[M].天津:天津大学出版社,1999.[4]夏宇闻.数字系统设计-Verilog实现[M].北京:高等教育出版社,2006.[5]王金明.Verilog HDL程序设计教程[M].北京:人民邮电出版社,2004.。

一个异步FIFO的设计示例

一个异步FIFO的设计示例

一、异步FIFO 技术规范 1. 总体描述1.1. 功能定义异步FIFO ( First In First Out)指的是在两个相互独立的时钟域下, 数据从一个时钟域写入FIFO 而另一个时钟域又从这个FIFO 中将数据读出。

本设计用8*256的RAM 实现异步FIFO 。

具体功能:1. 写使能有效,且FIFO 不为满时,在写时钟的上升沿向FIFO 中写入数据。

2. 读使能有效,且FIFO 不为空时,在读时钟的上升沿从FIFO 中读出数据。

3. 当FIFO 写满时产生满信号,当FIFO 读空时产生空信号。

1.2. 应用范围异步FIFO 是用来作为缓冲的存储器, 它能对数据进行快速、顺序的存储和发送, 主要用来解决不同速率器件间的速率匹配问题。

2. 引脚描述图12.1. 引脚功能描述2.2.引脚时序描述当写满时full由低变高,当读空时empty由低变高。

只要不为满full就为低,不为空empty就为低。

3.顶层模块划分图2顶层模块说明:1.ram_fifo :存储器模块,用于存放及输出数据;2.w_addr_reg : 保存访问RAM的写地址;3.r_addr_reg : 保存访问RAM的读地址;4.w_addr_adder : 计算RAM下一个写地址;5.r_addr_adder: 计算RAM下一个读地址;6.cmp : 将读地址和写地址进行比较产生空满标志。

设计思想说明:FIFO满空的判定:当读地址的值加1之后等于写地址的值时,表明FIFO写满,当写地址的值加一之后等于读地址的值时,表明FIFO读空。

在初始状态时FIFO的读地址在RAM的中间位置,写地址在RAM的开始位置,所以初始状态FIFO不满也不空。

空满信号的产生由组合电路产生。

4.功能模块描述4.1.ram_fifo模块ram_fifo:RAM存储器。

用8*256双口RAM实现。

4.2.w_addr_reg模块w_addr_reg模块:写地址寄存器。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于异步FIFO实现不同时钟域间数据传递的设计
[2006-12-1813:31:00|By:夏虫]
推荐
摘要:数据流在不同时钟域间的传递一直是集成电路芯片设计中的一个重点问题。

本文通过采用异步FIFO的方式给出了这个问题的一种解决方法,并采用Verilog硬件描述语言通过前仿真和逻辑综合完成设计。

关键词:异步FIFO;时钟域;Verilog
引言
当今集成电路设计的主导思想之一就是设计同步化,即对所有时钟控制器件(如触发器、RAM等)都采用同一个时钟来控制。

但在实际的应用系统中,实现完全同步化的设计非常困难,很多情况下不可避免地要完成数据在不同时钟域间的传递(如高速模块和低速模块之间的数据交换)。

这时,如何保持系统的稳定,顺利完成数据的传输就成为一个重要的问题,这也是异步电路设计中最为棘手的问题。

通常的做法是采用对每位信号加同步器或增加握手信号来解决这一问题,但这样会增加系统的复杂度且影响传输速度。

本文的做法是在两个时钟域的交界处设计一个异步FIFO,通过它来实现数据流的传输。

由发送时钟域将数据写入,接收时钟域将数据取出,在数据传输的同时实现了数据的缓存,因此是一种较理想的方法。

不同时钟域间数据传递的
问题及其解决方法
不同时钟域间数据传递的最重要问题就是亚稳态问题。

当数据信号通过两个时钟域的交界处时,将会分别由这两个时钟来控制信号的值。

此时如果两时钟信号的敏感沿非常接近并超过了允许的额度,则将出现数据信号的不稳定,即电路陷入亚稳态,也称为同步失败。

亚稳态是在两时钟敏感沿靠得很近、第二级时钟敏感沿到来时其输入数据不稳时发生,可将其视为仅仅是第二级触发器输入信号不稳定所导致的结果。

只要使输入信号稳定,就能解决亚稳态问题。

针对如上所述亚稳态的特点,可设计一个同步器来保证数据的稳定传输以解决这个问题。

其原理在于使信号在新的时钟域中先稳定下来再进入相关的逻辑,以保证信号与新的时钟同步。

本设计在时钟域的接口处就采用此法。

异步FIFO模块设计及实现
异步FIFO结构设计
本文所设计的异步FIFO采用循环队列方式,由独立的两个时钟Iclk和Oclk来控制读、写指针。

模块结构如图1所示。

输入端口:输入端时钟Iclk,输出端时钟Oclk,8位并行输入数据Din,复位信号Rst_。

输出端口:8位并行输出数据Dout,FIFO写满信号Full,FIFO读空信号Empty。

信号后缀:i—由输入时钟域控制、o—由输出时钟域控制、g—GRAY码、b—二进制自然码。

由于FIFO的空、满是通过比较读、写指针来确定的,而读、写指针分别属于Oclk 和Iclk两个时钟域,所以对其比较时要进行同步化处理,即用到双触发器型同步器,以避免亚稳态的出现。

以写指针Wp为例。

Wpib转换为Wpig,一方面控制Din 的写入地址,另一方面通过同步和GRAY到二进制码转换送入到Oclk。

本文将传输的Wp由GRAY码形式转换为二进制形式,形成Wpob。

此时Wpob与Rpob为同步信号,比较其大小后可判断FIFO是否读空来控制FlagE信号。

若FIFO为空,则FlagE置Empty信号,同时调整Rpob停止读出数据。

同理可知Rp和Full的控制过程。

在整个数据流动过程中,需要跨过时钟域的指针经历了两次码制的变化:二进制码到GRAY码和GRAY码到二进制码。

前者是利用GRAY码在递增时每次只有一位发生变化的特点,以GRAY码的形式通过时钟域分界线最大限度减小了指针信号的变化,避免了信号传输中的抖动。

而再将信号由GRAY码转换为二进制码进行比较则是由FIFO异步的特点所决定。

由于读、写指针异步,不存在稳定的相对关系,为避免读、写指针同时对一个存储单元进行操作,在对FIFO做空、满比较时会对指针差留下一定余量。

由于GRAY码形式不易于直接比较这种有固定差额的数值,所以将其转化为二进制码进行比较。

HDL实现
下面采用Verilog HDL语言在RTL级上设计此异步FIFO数据通道。

此方案的核心在于GRAY码到二进制的转换和同步器的设计,均在同步和GRAY到二进制码转换模块中实现,程序如下:
……
always@(posedge Oclk or negedge Rst_)//Oclk domain synchronization
if(!Rst_)
……//initialize Wpmg1,Wpmg2and Wpob
else
begin
Wpmg1&lt;=Wpig;
Wpmg2&lt;=Wpig1;
Wpob[0]&lt;=Wpmg2[5]^Wpmg2[4]^Wpmg2[3]^Wpmg2[2]^Wpmg2[1]
^Wpmg2[0];//GRAY to binary
Wpob[1]&lt;=Wpmg2[5]^Wpmg2[4]^Wpmg2[3]^Wpmg2[2]^Wpmg2[1];
……
Wpob[0]&lt;=Wpmg2[5];
end
……
如上程序所示,以写指针为例,输入时钟GRAY码写指针Wpig进入输出时钟域后赋给两个串行寄存器Wpmg1、Wpmg2,此后将Wpmg2变换成二进制码并传输给下一级寄存器Wpob。

这样就完成跨时钟域数据的同步化并实现了码制的变换。

这样,当读、写信号被顺利同步化以后,实际上其中通过时钟域边界的信号(仍以Wpob为例)已被同步器延迟了两个Oclk周期,在这段时间内Wpib有可能已经在Iclk作用下增加了。

如果使用“Wpob=Rpob”为条件来判断FIFO达到空状态,则此时实际控制读FIFO主体的指针Wpig可能已继续下行,导致读出错误的数据。

为避免这种情况的出现,进行指针比较时是留有一定余地的,具体程序如下:……
parameter DIFF=3’b100;
……
assign FlagE=((Wpob&lt;=Rpob+DIFF)&amp;&amp;(Wpob&gt;=Rpob))?1:0;……
如上程序所示,以空标志为例,比较的是保留了4位的“即空”状态,即读指针离写指针还差4个周期时,就认为其读“空”,从而置读空标志FlagE。

对于一个FIFO而言,数据流在其中是连续流动的,“即空”状态的判断是通过减小FIFO的最大容量来保证传输的稳定。

仿真验证和综合
设系统复位后Din输入为从0开始每Iclk周期加1至63的循环变化数据。

如果仿真时钟周期Iclk设为30ns、Oclk设为50ns,所得结果如图2所示。

从图2中可以看到,当输入时钟频率大于输出时钟频率时会出现数据写满的情况。

因为此时写时钟是快时钟,故写满比较发生在输入时钟域。

当比较到两指针差等于定义的DIFF值(此时为4)时,由Iclk触发写满信号给前级系统。

同理可得空状态的仿真也能达到设计要求。

对于逻辑综合,本文使用Synopsys公司的Design Compiler工具实现ASIC综合。

通过生成的Violators.rpt、area.rpt、tim_max.rpt、lib.rpt等报告观察综合所得电路的特性,可知此设计无violated constraints,表明综合结果能够达到约束条件的要求,此设计能在给定条件下工作,即约束成功。

结语
本文讨论了异步设计中数据在不同时钟域间传递所产生的亚稳态问题及其解决方法,使用Verilog HDL,采用Top-Down的模块设计方法实现了一种解决此问题的异步FIFO方案。

经验证这种方案能方便安全地实现数据跨时钟域的传递,并能同时起到数据缓存的作用,因此是一种较好的解决方法。


参考文献
1A.Chakraborty,M.R.Greenstreet A minimal source-synchronous interface, ASIC/SOC Conference,2002.15th Annual IEEE International,25-28Sept. 2002Page(s):443-447
2William J.Dally,John W.Poulton Digital Systems Engineering, CambridgeUniversity Press,1998,Page(s):468.
3Clifford E.Cummings Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Designs,Sunburst Design,Inc.。

相关文档
最新文档