星空-异步FIFO设计,搞清楚这7点就够了!

异步FIFO设计,弄清晰这7点就够了! 时候:2024-12-19 18:30:41 手机看文章

扫描二维码随时随地手机看文章

 

1、甚么是格雷码(Gray Code)?

格雷码是美国粹者Frank Gray在1947年提出的一种二进制编码体例,后面这类编码体例就以他的名字定名。现实上,格雷码是有多种编码情势的。按照界说,在一组数的编码中,若肆意两个相邻的代码只有一名二进制数分歧,则称这类编码为格雷码。

下表是分歧情势的格雷码:

表中典型格雷码具有代表性。若不作特殊申明,格雷码就是指典型格雷码(后文将简称格雷码),它可从天然二进制码转换而来。

好了,此刻我问你,按照格雷码的性质你能默写出16个4bit宽度的格雷码来吗?我想通常为比力难的,由于单靠上述性质很难推导出来。好比说,0(0000)可以写出来,1(0001)也能够写出来,2(0011)也能够写出来,可是3就欠好写了,由于按照只能转变一名的性质,可所以0111,也能够是0010,那末究竟是哪一个呢?若何不是常常利用的话,我想是很难判定的。

所以接下来就要介绍格雷码的第二个性质了:当第N位从0变到1的时辰,以后的数的N-1位会关在前半段轴对称,而比N位高的位是不异的。

我们看一下4bit格雷码的前四位的例子。示意图以下:

•当0001跳转到下一名时,无庸置疑的是,第0位会保持1不变,而第1位会跳转到1,所以可以据此画出对称轴

•高2位(第3、2位)这连结不变

•低位(该实例中只有第0位)关在对称轴对称

有了上述三点信息,那末便可以把剩下的2个格雷码写出来了。

4bit格雷码的前8位示意图以下(这我就不烦琐了,你们必定看得懂):

2、异步FIFO为何要利用格雷码?

异步FIFO设计最要害的点是甚么?谜底是“空”和“满”的判定。此刻回忆一下,我们是若何进行状况判定的。很简单,别离构建读指针和写指针。写指针老是指向下一个要写的地址,而读指针永久指向当前要读取的地址。再经由过程对读、写指针的比力来判定空、满。

如上图的FIFO深度为8,则其地址位宽应当是3(2的三次方等在8)。当写指针与读指针都指向统一个位置(即不异)时,多是空状况,但也多是满状况(写指针跨越了读指针一圈)。(这里说句题外话,不成能是读指针跨越写指针一圈,由于但读、写指针第一次相等时,就应当输出空状况,然后住手对FIFO进行读取操作。)所以,事实若何判定FIFO是空仍是满呢?谜底是没法判定,只能经由过程在高位增添一名的体例来判定,当除最高位MSB外的其他位都不异,最高位分歧时则注解此时写指针跨越了读指针一圈,FIFO被写满了;当除最高位MSB外的其他位都不异,最高位不异时则注解此时写指针等在读指针,FIFO被读空了。

这类方式用来对同步FIFO进行判定是没有问题的,由于同步FIFO的读、写指针是统一时钟域下的旌旗灯号,可以直接对照。可是异步FIFO的读、写指针是分歧时钟域下的旌旗灯号,假如直接对照则会有亚稳态的问题。为了对异步FIFO的读、写指针进行判定,我们起首需要将其同步到同一的时钟域下,而这就激发出了新的问题----读、写指针在年夜大都环境下都不是个单bit旌旗灯号,而是个多bit旌旗灯号。假如读、写指针直接利用2进制的情势进行同步,则难以免同步进程中会呈现的多个bit旌旗灯号同时转变的问题。如7(0111)跳转到8(1000),此时有4个bit旌旗灯号都产生了转变,假如直接同步,则因为分歧旌旗灯号之间的延迟(skew),可能致使亚稳态、错采、漏采等等问题。

此时无妨回忆下格雷码的性质:每相邻位之间只有一个bit的转变。FIFO的指针是递增的,这使得在传输递增的多bit旌旗灯号时,格雷码具有自然的优势。仍是从7到8的例子,若利用格雷码,则应当是7(0100)--8(1100),如许就只有1个bit的转变了(最高位),如许就将多bit旌旗灯号的跨时钟域改变成了单bit旌旗灯号的跨时钟域,而单个bit的跨时钟域同步是很好实现的。

3、读指针、写指针应当被同步到哪一个时钟域?

异步FIFO的读、写指针是分歧时钟域的旌旗灯号,那末就不克不及直接对照,而是需要将其同步到统一时钟域才能进行对照。此刻问题来了?指针应当被同步到哪一个时钟域?可选项有第三方时钟域、读时钟域和写时钟域。接下来无妨逐一阐发。

起首需要申明的是,这说的同步都是指利用2个(或3个,但此类环境不多)FF(触发器)来进行同步(俗称“打两拍”),这类同步体例是有延迟的(时序开消,可以看作是两个目同步时钟周期)。

第三方时钟域:不难知道一个旌旗灯号从一个时钟域同步到另外一个时钟域(被同步时钟域)是需要时候的(这里仅斟酌从满到快,也就是临时不斟酌漏采的问题),需要的时候取决在被同步时钟域的周期和需要同步的个数。假定这个时候是T,那末颠末T时候后,因为读写时钟纷歧致,本来的读写时针增添(也可能不变)的量是纷歧致。好比说现实上读写时针都指向4(且最高位不异),那末这类环境现实上是呈现了读空的环境。可是同步到第三方时钟域后,可能写指针成了6,而读指针酿成了8(读时钟比写时钟快),那末在这类环境下FIFO就不会报“读空”,从而造成功能错乱。所以该种方式不成取。

同步到写时钟域:读指针同步到写时钟域需要时候T,在颠末T时候后,可能本来的读指针会增添或不变,也就是说同步后的读指针必然是小在等在本来的读指针的。写指针也可能产生转变,可是写指针原本就在这个时钟域,所所以不需要同步的,也就意味着进行对照的写指针就是真实的写指针。

此刻来进行写满的判定:也就是写指针跨越了同步后的读指针一圈。可是本来的读指针是年夜在等在同步后的读指针的,所以现实上这个时辰写指针实际上是没有跨越读指针一圈的,也就是说这类环境是“假写满”。那末“假写满”是一种毛病的设计吗?谜底是NO。前面我们说过异步FIFO设计的要害点是发生适合的“写满”和“读空”旌旗灯号,那末何谓“适合”?该报的时辰没报算适合吗?固然不算适合。不应报的时辰报了算不算适合?谜底是算。可以想象一下,假定一个深度为100的FIFO,在写到第98个数据的时辰就报了“写满”,会引发甚么后果?谜底是不会造成功能毛病,只会造成机能损掉(2%),年夜不了FIFO的深度我罕用一点点就是的。事实上这还可以算是某种水平上的守旧设计(平安)。

接着进行读空的判定:也就是同步后的读指针追上了写指针。可是本来的读指针是年夜在等在同步后的读指针的,所以现实上这个时辰读指针现实上是跨越了写指针。这类环境意味着已产生了“读空”,却依然有毛病数据读出。所以这类环境就造成了FIFO的功能毛病。

同步到读时钟域:写指针同步到读时钟域需要时候T,在颠末T时候后,可能本来的读指针会增添或不变,也就是说同步后的写指针必然是小在等在本来的写指针的。读指针也可能产生转变,可是读指针原本就在这个时钟域,所所以不需要同步的,也就意味着进行对照的读指针就是真实的读指针。

此刻来进行写满的判定:也就是同步后的写指针跨越了读指针一圈。可是本来的写指针是年夜在等在同步后的写指针的,所以现实上这个时辰写指针已跨越了读指针不止一圈,这类环境意味着已产生了“写满”,却依然数据被笼盖写入。所以这类环境就造成了FIFO的功能毛病。

接着进行读空的判定:也就是读指针追上了同步后的指针。可是本来的写指针是年夜在等在同步后的写指针的,所以现实上这个时辰读指针其实还没有追上写指针,也就是说这类环境是“假读空”。那末“假读空”是一种毛病的设计吗?谜底是NO。前面我们说过异步FIFO设计的要害点是发生适合的“写满”和“读空”旌旗灯号,那末何谓“适合”?该报的时辰没报算适合吗?固然不算适合。不应报的时辰报了算不算适合?谜底是算。可以想象一下,假定某个FIFO,在读到还剩2个数据的时辰就报了“读空”,会引发甚么后果?谜底是不会造成功能毛病,只会造成机能损掉(2%),年夜不了我先不读了,等数据多了再读就是的。事实上这还可以算是某种水平上的守旧设计(平安)。

此刻可以总结一下:

• “写满”的判定:需要将读指针同步到写时钟域,再与写指针判定

• “读空”的判定:需要将写指针同步到读时钟域,再与读指针判定

假读空示意以下:

假写满示意以下:

4、若何判定异步FIFO的空和满?

在同步FIFO的设计中,我们把读、写指针的位宽拓宽了1bit,目标是辨别本来的读、写指针相等时判定空、满的问题。同步FIFO的指针利用的是2进制码的情势,而异步FIFO为了削减多bit旌旗灯号跨时钟域传输的亚稳态问题,采取的是格雷码情势的指针,那末格雷码情势的指针应当若何对照来判定空和满?

起首要申明的是,将格雷码转换成2进制再进行对照是一种很好的法子,可是会耗损多的组合逻辑资本,所以我们临时不会商。

先不雅察上图,假定我们要设计的FIFO深度为8,那末指针宽度是4,由于宽度为3时没法辨别空、满。

空的判定很好判定,只要读写指针所有位全数一致,则申明此时是空状况。

满的判定复杂一点,假定采取同步FIFO的判定方式----最高位分歧,其他位一致。我们用现实的数值来看看是甚么环境:当读指针的值为0100,则申明此时读指针指向最高的空间7,那末若是FIFO满了,则写指针应当是1100,那末1100对应的二进制是几多呢?是8。那末读写指针、一个指向7,另外一个却指向8,这是满?明显不是。

假如真的是满的话,写指针应当是几多?应当是15,也就是1000,此时写指针是跨越读指针8,也就是一圈的。那末0100和1000有甚么联系?很明显,高两位相反,低位不异。这类纪律的构成缘由是我们之条件到的,格雷码的转变都关在某个对称轴对称。

总结:

• 当最高位和次高位不异,其余位不异认为是读空

• 当最高位和次高位分歧,其余位不异认为是写满

5、空和满的判定是正确的吗?

在第4点我们知道了----将读指针同步到写时钟域来判定满;将写指针同步到读时钟域来判定空。既然是异步FIFO,那末读写时钟域的旌旗灯号是纷歧致的,此中一个的频率快,另外一个的频率这慢。那末在两次同步进程中,必然是一次慢时钟采快时钟和一次快时钟采慢时钟。快时钟采慢时钟是不会有问题的,由于这合适采样定理。可是慢时钟采快时钟则会有问题,由于采样进程不合适采样定理。

那末会造成甚么问题?谜底是漏采。某些数值可能会被漏失落。例如本来是持续的0--1--2---3的旌旗灯号,从快时钟同步到慢时钟后,就酿成了离散的0--3,此中的1、2被漏失落了。那末如许一种现象会致使空、满的判定是正确的吗?谜底是禁绝确,但不妨。

假想读慢写快与读快写慢两种环境:

读慢写快:

进行写满判定的时辰需要将读指针同步到写时钟域,由于读慢写快,所以不会有读指针漏掉,同步耗损时钟周期,所以同步后的读指针滞后(小在等在)当前读地址,所以可能写满会提早发生,并不是真写满。

进行读空判定的时辰需要将写指针同步到读指针 ,由于读慢写快,所以当读时钟同步写指针的时辰,必定会漏失落一部门写指针,我们不消关心那到底会漏失落哪些写指针,我们在意的是漏失落的指针会对FIFO的读空发生影响吗?好比写指针从0写到10,时代读时钟域只同步捕获到了3、5、8这三个写指针而漏失落了其他指针。当同步到8这个写指针时,真实的写指针可能已写到10 ,相当在在读时钟域还没来得和发觉的环境下,写时钟域可能写了数据到FIFO去,如许在判定它是否是空的时辰会呈现不是真正空的环境,漏失落的指针也没有对FIFO的逻辑操作发生影响。

读快写慢:

进行读空判定的时辰需要将写指针同步到读指针 ,由于读快写慢,所以不会有写指针漏掉,同步耗损时钟周期,所以同步后的写指针滞后(小在等在)当前写地址,所以可能读空会提早发生,并不是真读空。

进行写满判定的时辰需要将读指针同步到写时钟域,由于读快写慢,所以当写时钟同步读指针的时辰,必定会漏失落一部门读指针,我们不消关心那到底会漏失落哪些读指针,我们在意的是漏失落的指针会对FIFO的写满发生影响吗?好比读指针从0读到10,时代写时钟域只同步捕获到了3、5、8这三个读指针而漏失落了其他指针。当同步到8这个读指针时,真实的读指针可能已读到10 ,相当在在写时钟域还没来得和发觉的环境下,读时钟域可能从FIFO读了数据出来,如许在判定它是否是满的时辰会呈现不是真正满的环境,漏失落的指针也没有对FIFO的逻辑操作发生影响。

此刻我们会发现,所谓的空满旌旗灯号现实上是禁绝确的,在还没有空、满的时钟就已输出了空满旌旗灯号,如许的空满旌旗灯号一般称为假空、假满。假空、假满旌旗灯号素质上是一种守旧设计,想象一下,一个深度为16的异步FIFO,在其写入14个数据时,即输出了写满(假满)标记,这会对我们的设计造成影响吗?会,会减弱我们的效力,我们现实利用的FIFO深度成了14,可是会使得我们的设计发生毛病吗?明显不会。一样的,在FIFO深度仍有2时即输出了读空(假空)标记,也不会使得我们的设计犯错,可是会下降效力,由于我们利用的FIFO深度又少了2。

6、既然有假满、假空,那末有无真满、真空?

还真有,可是没意义。既然我们可以将读指针同步到写时钟域来判定假满;将写指针同步到读时钟域来判定假空。那末对应地,可以读指针同步到写时钟域来判定空;将写指针同步到读时钟域来判定满。

在写时钟域判定空:

读指针被同步过来的旌旗灯号(同步后读指针)是滞后在真实读指针的旌旗灯号,当同步后读指针等在写指针时,真实读指针现实上早就等在写指针了,也就是说此时的空必然是空,乃至已空了一段时候了。如许的空标记明显是没有利用意义的,由于会造成对FIFO的过读操作,你来往返回读个空FIFO有甚么意义呢?也就是说真空能实现,可是没现实利用意义。

在读时钟域判定满:

写指针被同步过来的旌旗灯号(同步后写指针)是滞后在真实写指针的旌旗灯号,但同步后写指针跨越读指针一圈时,真实写指针现实上早就跨越读指针一圈了,也就是说此时的满必然是满,乃至已满了一段时候了。如许的满标记明显是没有利用意义的,由于会造成对FIFO的过写操作,你来往返回写个满FIFO有甚么意义呢?也就是说真满也能实现,可是一样没现实利用意义。

7、非2次幂深度的FIFO若何设计?

在第1点关在格雷码的性质中,我们论述了:

• 在一组数的编码中,若肆意两个相邻的代码只有一名二进制数分歧,则称这类编码为格雷码

• 当第N位从0变到1的时辰,以后的数的N-1位会关在前半段轴对称,而比N位高的位是不异的。

由这两点,我们发现格雷码都可以关在某条对称轴对称。所以只有当FIFO深度为2的幂次方时,才能做到格雷码绕一圈后,回到初始位置依然只有1bit转变,如15(1000)----0(0000)。当FIFO深度不为2的幂次方时,明显从最尾端跳转到开首端,转变的就不止一个bit了。好比FIFO深度为7,明显,从13(1011)----0(0000),转变了可不止1bit。如许的话在这一次跳变就掉去了格雷码存在的意义了,所以得想点其他法子解决。

前面说过,格雷码相邻每位只转变1bit,并且关在中轴对称的。那末我们可以如许编码:针对深度为7的FIFO,从1(0001)最先,一向到(14个数暗示7深度,高位辨别状况)14(1001),1(0001)与14(1001)是关在中轴对称的(高位为转变位),所以也只有1bit的跳变。一样的假如深度为6的FIFO,就从2(0011)最先,到13(1011),一样只跳变1bit。

空标记只用判定读、写指针是不是全数相等便可。可是满标记就不克不及用“高两位相反,其他位不异来判定了”,需要找其他纪律了。从这里可以看出,格雷码作为一种无权码,在比力和运算等方面不若有权码二进制矫捷。所以,咱要不仍是转回二进制再比力吧。

不管你设计FIFO用RAM仍是直接挪用IP也好,终究实现都是用的Block RAM资本,其生成的位宽必定是2的幂次。所以啊,不消也是华侈啊。

欲知详情,请下载word文档 下载文档

上一篇:星空-自动化 下一篇:星空-机器人