异步fifo空满判断,异步fifo中同步为什么要用两级触发器
异步fifo空满判断,异步fifo中同步为什么要用两级触发器详细介绍
本文目录一览: 异步fifo中同步为什么要用两级触发器
异步FIFO通过比较读写地址进行满空判断,但是读写地址属于不同的时钟域,所以在比较之前需要先将读写地址进行同步处理,将写地址同步到读时钟域再和读地址比较进行FIFO空状态判断(同步后的写地址一定是小于或者等于当前的写地址,所以此时判断FIFO为空不一定是真空,这样更保守),将读地址同步到写时钟域再和写地址比较进行FIFO满状态判断(同步后的读地址一定是小于或者等于当前的读地址,所以此时判断FIFO为满不一定是真空,这样更保守),这样可以保证FIFO的特性:FIFO空之后不能继续读取,FIFO满之后不能继续写入。
大多数情形下,异步FIFO两端的时钟不是同频的,或者读快写慢,或者读慢写快,这时候进行地址同步的时候,可能会有地址遗漏,以读慢写快为例,进行满标志判断的时候需要将读地址同步到写时钟域,因为读慢写快,所以不会有读地址遗漏,同步后的读地址滞后当前读地址,所以可能满标志会提前产生。进行空标志判断的时候需要将写地址同步到读地址,因为读慢写快,所以当读时钟同步写地址的时候,必然会漏掉一部分写地址(写时钟快,写地址随写时钟翻转,直到满标志出现为止),那到底读时钟会同步到哪个写地址?不必在意是哪一个,我们关注的是漏掉的地址会不会对FIFO的空标志产生影响。比如写地址从0写到10,期间读时钟域只同步到了2,5,7这三个写地址,漏掉了其他地址。同步到7地址时,真实的写地址可能已经写到10地址,相当于“在读时钟域还没来得及觉察的情况下,写时钟域可能偷偷写了数据到FIFO去”,这样在比较读写地址的时候不会产生FIFO“空”读操作。漏掉的地址也没有对FIFO的逻辑操作产生影响。
我们可以对异步FIFO的地址采用binary编码,这样并不影响异步FIFO的功能,前提是读写地址同步时能够保持正确。这种情况在功能仿真时完全正确,问题只有到时序仿真时才会遇到。毛刺可以说是异步电路的杀手,一个毛刺被触发器采样后会被放大,然后传播,导致电路功能出错。binary编码的地址总线在跳变时极易产生毛刺,因为binary编码是多位跳变,在实现电路时不可能做到所有的地址总线等长,address bus skew必然存在,而且写地址和读地址分属不同时钟域,读写时钟完全异步,这样地址总线在进行同步过程中出错不可避免,比如写地址在从0111到1000转换时4条地址线同时跳变,这样读时钟在进行写地址同步后得到的写地址可能是0000-1111的某个值,这个完全不能确定,所以用这个同步后的写地址进行FIFO空判断的时候难免出错。
这个时候gray码体现了价值,一次只有一位数据发生变化,这样在进行地址同步的时候,只有两种情况:1.地址同步正确;2.地址同步出错,但是只有1位出错;第一种正确的情况不需要分析,我们关注第二种,假设写地址从000->001,读时钟域同步出错,写地址为000->000,也就是地址没有跳变,但是用这个错误的写地址去做空判断不会出错,最多是让空标志在FIFO不是真正空的时候产生,而不会出现空读的情形。所以gray码保证的是同步后的读写地址即使在出错的情形下依然能够保证FIFO功能的正确性,当然同步后的读写地址出错总是存在的(因为时钟异步,采样点不确定)。这里需要注意gray码只是在相邻两次跳变之间才会出现只有1位数据不一致的情形,超过两个周期则不一定,所有地址总线bus skew一定不能超过一个周期,否则可能出现gray码多位数据跳变的情况,这个时候gray码就失去了作用,因为这时候同步后的地址已经不能保证只有1位跳变了。
另外需要将地址总线打两拍,这是为了避免亚稳态传播,理论上将打两拍不能消除亚稳态现象,因为时钟异步,亚稳态不可避免,但是可以极大降低亚稳态传播的概率,低频情况下甚至STA不需要分析这里的异步时序,因为寄存器都可以在一拍内将亚稳态消除,恢复到正常0/1态。而在高频情况下则不一定,尤其在28nm工艺以下,需要检查两级触发器的延迟,保证延迟低,这样可以提高Tr,提高系统MTBF。
i2c中的fifo是异步的还是同步的
根据FIFO工作的时钟域分为同步/异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟在时钟沿来临时同时发生读写。异步FIFO读写时钟不一致,读写相互独立。异步FIFO最核心的部分就是精确产生空满标志位,这直接关系到设计的成败。为了定位读取和写入的位置需要进行读写指针的设置。读指针:总是指向下一个将要读取的单元,复位时指向第一个单元(编号为0)。写指针:总是指向当前要被读出的数据,复位时指向第一个单元(编号为0)。当第一次读写指针相等时,表明FIFO为空,这种情况发生在复位操作时或者当读指针读出FIFO中最后一个字后,追赶上写指针时,此时读空信号有效。当读写指针再次相等时,表明FIFO为满,这种情况发生在,当写指针转了一圈折回来(wrappedaround)又追上了读指针。两种方式都是以读写指针相等作为判断标志。
传统的异步fifo怎么通过地址同步实现空满标志
#120 cis_0 = 10'h155
#20 WR = 1;
/ / cis_0 =保持10'h155的520ns,写时钟周期为120ns的,写了四10'h155,后cis_0 = 10'h0
写10'h0
#500 cis_0的= 10'h0;
#90 RD = 1;
#100
/ / RD持续100ns的,读的时钟周期是40ns的数据可以读出两个,应该是10'h155,10'h155
您的测试平台是不太好,没有足够的数据,一个大时钟周期。很短的时间。
建议:1。经常写比读频率大,你可以写时钟为10ns,读时钟为20ns。
2。输入数据随机抽取形成,方便观察,而且还节省时间,使用总是#10 cis_0的= {$随机}%1024
3。测试时间要大点,与最初的。 。 。 #10000 $停止;
FIFO原则是什么?
FIFO 是First In first Out的首字母缩略词。 先进先出。
这个表示描述队列的原则: 什么首先进来首先被处理, 什么进来下等待直到一被完成, 等。因而它是analagous 对人行为"站立在线" (更喜欢在美国英语) 或"队列" (更喜欢在英国英语), 人事假队列在次序他们到达的地方。
优先权队列是变异在在名字不合格FIFO 的队列, 因为它准确地不是描写的那数据结构的行为。排队的理论包含队列的更加一般的概念, 并且互作用在严密Fifo 队列之间。
表示 FIFO 可能被利用在另外环境:
为人队列, 参见 队列区域。
在计算机科学方面这项条款提到数据被存放在队列被处理的方式。各个项目在队列被存放在队列(simpliciter) 数据结构。第一数据增加来队列将是第一数据被去除, 然后处理连续地进行在同样次序。这是典型的行为为队列, 但看见也LIFO 和堆积算法。
在电子 FIFO 是第一数据被写总是第一数据读的一台半导体存储器。作用是可利用的作为包括地址计数器、控制逻辑和SRAM 的集成电路。FIFO 以时钟输入称同步FIFO; 否则它是异步的。设备典型地有产品叫做表明的旗子它是空的或充分。
在会计, FIFO 是一个通常方法为接近存货的价值。它是适当的有许多不同的批相似的产品的地方。方法假定, 下个项目运输将是最老的那键入仓库。实践上, 这反映部下的商业物质。参见LIFO 在这环境。
FIFO(First IN First Out)先进先出电路
实现数据先进先出的存储器件,FIFO的用途:普遍用作数据缓冲器,可以用在电话通讯网络的前端来同步输入的网络数据包。也可以用于顺序数据的缓冲,比如音频信号或视频信号。另一个广泛的应用是在处理器之间的通讯中。
FIFO的基本单元是寄存器,作为存储器件,FIFO的存储能力是由其内部定义的存储寄存器的数量决定 . FIFO存储器一般以数据量的深度X宽度的形式来说明所采用的基本结构
第一代FIFO存储器是基于“导向”理论的,数据从输入端被移到输出端,所需要的时间称为导向时间
每一个数据字需要一个状态触发器,因此对数据锁存的控制只能实现很短的FIFO的操作
以长度为8的FIFO为例说明其工作原理。入图所示
____________________
D, C, B, A ——> | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8|———>
两边的箭头表示数据移动的方向。A,B,C,D表示被处理的数据。1,2,3,4,。。。8表示FIFO的8个存储单元。表明这个FIFO中共有8个寄存器单元。每个寄存器单元可以存储一个数据。所以寄存器的单元越多,FIFO的存储能力就越强。每个寄存器单元的位宽与FIFO的输入和输出端的位宽是一致的。如果要处理的数据A,B,C,D是16位的数据,那么输入输出端及每个寄存器单元的位宽就都是16位。这个FIFO可以命名为8X16FIFO。它在每一个时钟上升沿到来时,数据向右移动一个存储单元。这样在时钟的控制下,数据从左到右通过存储单元
FIFO通常是双端口的存储器,其中一个端口用于写入数据,而另一个端口用于读出数据。可以同时对存储器字存储单元进行写入和读出操作。它的数据吞吐率是普通RAM的两倍。
FIFO型的存储器不需要由地址来存取数据。需要由另外的信号线(或标志)来指明存储器的内容状态。
现在的FIFO存储器采用SRAM单元来实现。它是基于带两个指针的环行FIFO结构的。要写入的数据的存储地址放在写指针中,而FIFO结构中要读出的第一个数据的地址放在读指针中
在复位后,两个指针都指向存储器的同一个字单元。每次写操作后,写指针指向下一个存储单元。对数据字的读取操作,会把读指针指向下一个要读取的数据字
读指针就不断地跟随写指针,当读指针跟上写指针后,FIFO的结构里面为空。
如果写指针追上读指针,FIFO结构里面的数据是满载的。
如果从硬件上来实现循环存储器,可以用双端口的SRAM来存取数据。指针具用二进制计数器的特征,它用于产生SRAM的存储器地址
同步FIFO存储器的基本结构包括存储器阵列,标志逻辑和扩展逻辑(图太难画了,就不贴了)。
存储器阵列由双端口存储单元构成。允许同时对存储单元的两个端口(读端口和写端口)进行存取。
标志逻辑用于比较两个地址指针的值,如果两个值的比较结果为零,FIFO存储器为全空,同时全空标志为真。如果两个值的比较结果等于存储器的容量深度,说明存储器全满,同时全满标志为真。
还可以设置其他一些标志,比如半满,可编程接近满,可编程接近空等。它们也通过对偏移量寄存器中的编程值和存储器阵列中的字的数量进行比较来生成
(在张老师的课上,讲到读写时序的时候,关于标志逻辑,讲的太快,没有太深的体会,还需要看书1)
扩展逻辑通过对多个模块按容量深度扩展结构进行的级联来形成更深的FIFO存储器,采用令牌传递方法来实现逻辑上容量更深的FIFO。
在普通模式下(没有进行容量,深度级联的模式),每一个地址在到达最大值后,会跳会到零。
在容量深度扩展模式下,当地址指针到达最大值后,一个脉冲信号会送到扩展端口,该端口把令牌传到另一个FIFO存储器中,(直到令牌重新传回来,这个地址指针才会增加)(这个地方还有点模糊,有待解决。问过张老师,他却给我讲的是两个FIFO的乒乓操作。由于我的思路不是很清晰,也没有继续问下去。当时张老师也要开始讲课了,不好再打扰。)
我好像在一些有关物流管理方面的书上看到过
好像是说仓库货品的先进先出的操作方式
什么是FIFO
FIFO: 一、先入先出队列(First Input First Output,FIFO)这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。 1.什么是FIFO? FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 2.什么情况下用FIFO? FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。 3.FIFO的一些重要参数 FIFO的宽度:也就是英文资料里常看到的THE WIDTH,它指的是FIFO一次读写操作的数据位,就像MCU有8位和16位,ARM 32位等等,FIFO的宽度在单片成品IC中是固定的,也有可选择的,如果用FPGA自己实现一个FIFO,其数据位,也就是宽度是可以自己定义的。 FIFO的深度:THE DEEPTH,它指的是FIFO可以存储多少个N位的数据(如果宽度为N)。如一个8位的FIFO,若深度为8,它可以存储8个8位的数据,深度为12 ,就可以存储12个8位的数据,FIFO的深度可大可小,个人认为FIFO深度的计算并无一个固定的公式。在FIFO实际工作中,其数据的满/空标志可以控制数据的继续写入或读出。在一个具体的应用中也不可能由一些参数算数精确的所需FIFO深度为多少,这在写速度大于读速度的理想状态下是可行的,但在实际中用到的FIFO深度往往要大于计算值。一般来说根据电路的具体情况,在兼顾系统性能和FIFO成本的情况下估算一个大概的宽度和深度就可以了。而对于写速度慢于读速度的应用,FIFO的深度要根据读出的数据结构和读出数据的由那些具体的要求来确定。 满标志:FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出(overflow)。 空标志:FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出(underflow)。 读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。 写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。 读指针:指向下一个读出地址。读完后自动加1。 写指针:指向下一个要写入的地址的,写完自动加1。 读写指针其实就是读写的地址,只不过这个地址不能任意选择,而是连续的。 4.FIFO的分类 根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。 5.FIFO设计的难点 FIFO设计的难点在于怎样判断FIFO的空/满状态。为了保证数据正确的写入或读出,而不发生溢出或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。在空的状态下不能进行读操作。怎样判断FIFO的满/空就成了FIFO设计的核心问题。由于同步FIFO几乎很少用到,这里只描述异步FIFO的空/满标志产生问题。 在用到触发器的设计中,不可避免的会遇到亚稳态的问题(关于亚稳态这里不作介绍,可查看相关资料)。在涉及到触发器的电路中,亚稳态无法彻底消除,只能想办法将其发生的概率将到最低。其中的一个方法就是使用格雷码。格雷码在相邻的两个码元之间只有一位变换(二进制码在很多情况下是很多码元在同时变化)。这就会避免计数器与时钟同步的时候发生亚稳态现象。但是格雷码有个缺点就是只能定义2^n的深度,而不能像二进制码那样随意的定义FIFO的深度,因为格雷码必须循环一个2^n,否则就不能保证两个相邻码元之间相差一位的条件,因此也就不是真正的各雷码了。第二就是使用冗余的触发器,假设一个触发器发生亚稳态的概率为P,那么两个及联的触发器发生亚稳态的概率就为P的平方。但这回导致延时的增加。亚稳态的发生会使得FIFO出现错误,读/写时钟采样的地址指针会与真实的值之间不同,这就导致写入或读出的地址错误。由于考虑延时的作用,空/满标志的产生并不一定出现在FIFO真的空/满时才出现。可能FIFO还未空/满时就出现了空/满标志。这并没有什么不好,只要保证FIFO不出现overflow or underflow 就OK了。 很多关于FIFO的文章其实讨论的都是空/满标志的不同算法问题。 在Vijay A. Nebhrajani的《异步FIFO结构》一文中,作者提出了两个关于FIFO空/满标志的算法。 第一个算法:构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都相等时,FIFO为满(在Clifford E. Cummings的文章中以格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相等时,FIFO为空。这也许不容易看出,举个例子说明一下:一个深度为8字节的FIFO怎样工作(使用已转换为二进制的指针)。FIFO_WIDTH=8,FIFO_DEPTH= 2^N = 8,N = 3,指针宽度为N+1=4。起初rd_ptr_bin和wr_ptr_bin均为“0000”。此时FIFO中写入8个字节的数据。wr_ptr_bin =“1000”,rd_ptr_bin=“0000”。当然,这就是满条件。现在,假设执行了8次的读操作,使得rd_ptr_bin =“1000”,这就是空条件。另外的8次写操作将使wr_ptr_bin 等于“0000”,但rd_ptr_bin 仍然等于“1000”,因此FIFO为满条件。 显然起始指针无需为“0000”。假设它为“0100”,并且FIFO为空,那么8个字节会使wr_ptr_bin =“1100”,, rd_ptr_bin 仍然为“0100”。这又说明FIFO为满。 在Vijay A. Nebhrajani的这篇《异步FIFO结构》文章中说明了怎样运用格雷码来设置空满的条件,但没有说清为什么深度为8的FIFO其读写指针要用3+1位的格雷码来实现,而3+1位的格雷码可以表示16位的深度,而真实的FIFO只有8位,这是怎么回事?而这个问题在Clifford E. Cummings的文章中得以解释。三位格雷码可表示8位的深度,若在加一位最为MSB,则这一位加其他三位组成的格雷码并不代表新的地址,也就是说格雷码的0100表示表示7,而1100仍然表示7,只不过格雷码在经过一个以0位MSB的循环后进入一个以1为MSB的循环,然后又进入一个以0位MSB的循环,其他的三位码仍然是格雷码,但这就带来一个问题,在0100的循环完成后,进入1000,他们之间有两位发生了变换,而不是1位,所以增加一位MSB的做法使得该码在两处:0100~1000,1100~0000有两位码元发生变化,故该码以不是真正的格雷码。增加的MSB是为了实现空满标志的计算。Vijay A. Nebhrajani的文章用格雷码转二进制,再转格雷码的情况下提出空满条件,仅过两次转换,而Clifford E. Cummings的文章中直接在格雷码条件下得出空满条件。其实二者是一样的,只是实现方式不同罢了。 第二种算法:Clifford E. Cummings的文章中提到的STYLE #2。它将FIFO地址分成了4部分,每部分分别用高两位的MSB 00 、01、 11、 10决定FIFO是否为going full 或going empty (即将满或空)。如果写指针的高两位MSB小于读指针的高两位MSB则FIFO为“几乎满”, 若写指针的高两位MSB大于读指针的高两位MSB则FIFO为“几乎空”。 在Vijay A. Nebhrajani的《异步FIFO结构》第三部分的文章中也提到了一种方法,那就是方向标志与门限。设定了FIFO容量的75%作为上限,设定FIFO容量的25%为下限。当方向标志超过门限便输出满/空标志,这与Clifford E. Cummings的文章中提到的STYLE #2可谓是异曲同工。他们都属于保守的空满判断。其实这时输出空满标志FIFO并不一定真的空/满。 说到此,我们已经清楚地看到,FIFO设计最关键的就是产生空/满标志的算法的不同产生了不同的FIFO。但无论是精确的空满还是保守的空满都是为了保证FIFO工作的可靠。 ====================================================================================================================
编辑本段会计学:FIFO
二、先进先出法 (first in,first out ,FIFO) 先进先出法是指根据先入库先发出的原则,对于发出的存货以先入库存货的单价计算发出存货成本的方法.采用这种方法的具体做法是:先按存货的期初余额的单价计算发出的存货的成本,领发完毕后,再按第一批入库的存货的单价计算,依此从前向后类推,计算发出存货和结存货的成本. 先进先出法是存货的计价方法之一。它是根据先购入的商品先领用或发出的假定计价的。用先进先出法计算的期末存货额,比较接近市价。 先进先出法是以先购入的存货先发出这样一种存货实物流转假设为前提,对发出存货进行计价的一种方法。采用这种方法,先购入的存货成本在后购入的存货成本之前转出,据此确定发出存货和期末存货的成本。
1.什么是FIFO?
FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
FIFO: First in, First out.先进先出。
LIFO: Last in, First out.后进先出。
如A存货:本月1日购买10件,单价10元/件,3日购买20件,单价15元/件;10日购买10件,单价8元/件。
本月15日发货35件。
按FIFO先进先出,就是先购入的存货先发出,所以,先发1日进货的10件,再发3日进货的20件,最后发10日进货的5件,发出成本共为:10*10+20*15+5*8=440元。
按LIFO后进先出,就是后购入的存货先发出,所以,先发10日进货的10件,再发3日进货的20件,最后发1日进货的5件,发出成本共为:10*8+20*15+5*10=430元
按新会计准则,LIFO已不允许作为存货计价方法,因为其不符合实物流转的顺序。
FIFO是First Input First Output的缩写,先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。
是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单。
但缺点就是只能顺序写入数据,顺序读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
同步fifo和异步fifo的区别
当你的设计中只有一个时钟信号的时候,所有的寄存器都使用同一个时钟,他们之间不会产生传输速度不匹配的情况;而当你的设计中存在多个时钟信号,并且需要在这几个时钟域之间传输数据的时候,寄存器会由于时钟信号的频率不匹配而产生数据丢失等情况,这个时候需要用异步FIFO来进行缓存,保证数据能够正确传输,因此一般异步FIFO会包含一个双端口的RAM,用于数据记录,详细地可以参考FIFO的相关资料。这里的异步指的是不同频率/不同相位的时钟信号。而同步FIFO一般只用来作buffer。
大概就是这样子。
2.FIFO是不会实现数据位数的变换的。它只是实现了数据能被正确的传递。
同步就不用说了,异步时,当写满和读空时都有相应的信号告诉发送和接受模块,
这样就不会用冲突了
异步fifo读指针与写指针同一个位置时是满还是空
实际上你打?的地方做的是一个打2拍处理 这个操作在处理异步问题的时候很常用 由于异步fifo的读端和写端时钟不同步,因此需要解决异步时钟域的问题,会导致亚稳态 而将异步信号使用自己的时钟打2拍再进行使用可以有效避免亚稳态的传播
quartus调用altera内部的IP核 异步FIFO,在控制读写上如何进行控制,要求写满读,读空了写?最好有代码
代码如下:
`define ADDR_WIDTH 12 //地址位宽`define DATA_WIDTH 12 //数据位宽`define RAM_WIDTH 12 //RAM数据位宽`define RAM_DEPTH 4096 //RAM深度module fifo_test(clk_10M, //写时钟clk_5M, //读时钟rst_n, // 全局复位信号wr_en, // 写使能 低有效rd_en, // 读使能 低有效wr_data, //12位数据输入rd_data, //12位数据输出wr_full, // 写满标志 高有效rd_empty); // 读空标志 高有效//输入信号input clk_10M;input clk_5M;input rst_n;input wr_en;input rd_en;input[`DATA_WIDTH-1:0] wr_data;output reg [`DATA_WIDTH-1:0] rd_data;output reg wr_full;output reg rd_empty;reg [`RAM_WIDTH-1:0] mem[`RAM_DEPTH-1:0]; // 12位4096单元reg[`ADDR_WIDTH-1:0] wr_addr; // 12位写地址reg[`ADDR_WIDTH-1:0] rd_addr; // 12位读地址reg rd_flag;reg wr_flag;//写地址产生逻辑always @(posedge clk_10M or negedge rst_n)beginif(!rst_n)beginwr_addr <= 12'h0;wr_flag <= 0;endelse if(!wr_en)beginif(!wr_full && (rd_addr!=(wr_addr+1)))beginwr_flag <= 1;wr_addr <= wr_addr + 1'b1;endelsewr_flag <= 0;endend// 写数据产生逻辑always @(posedge clk_10M)beginif(!wr_en && !wr_full && wr_flag)mem[wr_addr] <= wr_data;end//写满产生标志always @(posedge clk_10M or negedge rst_n)beginif(!rst_n)wr_full <= 0;else if(rd_addr == (wr_addr+1))wr_full <= 1'b1;elsewr_full <= 1'b0;end//读地址产生逻辑always @(posedge clk_5M or negedge rst_n)beginif(!rst_n)beginrd_flag <= 0;rd_addr <= 12'd0;endelse if(!rd_en)beginif(!rd_empty && (wr_addr!=(rd_addr+1)))beginrd_flag <= 1;rd_addr <= rd_addr + 1'b1;endelserd_flag <= 0;endend//读数据产生逻辑always @(posedge clk_5M)beginif(!rd_en && !rd_empty && rd_flag)rd_data <= mem[rd_addr];end//读空产生标志always @(posedge clk_5M or negedge rst_n)beginif(!rst_n)rd_empty <= 1'b1;else if((wr_addr == (rd_addr+1))||(wr_addr == rd_addr))rd_empty <= 1'b1;elserd_empty <= 1'b0;endendmodule
请高手指教异步fifo的设计方法?谢谢了,大神帮忙啊
1.你说这个设计的空满信号不能及时释放,这个就是问题,因为正确的FIFO设计应该是空满信号能及时标记,以阻止读信号或者写信号,防止underrun和overrun的出现。我不是很清楚你说的gray encoded fifo是那种FIFO,最好能有代码或者功能的spec,这样的话能说得更清楚些。2.信号过不同时钟域用2个寄存器是为了防止亚稳态的出现,这个情况感觉主要出现在握手信号等。数据线和地址线过不同时间域情况比较少,不过如果需要也应当通过2个寄存器来保证信号的正确性。 查看原帖>>