異步FIFO設(shè)計(jì),搞清楚這7點(diǎn)就夠了!
掃描二維碼
隨時(shí)隨地手機(jī)看文章
1、什么是格雷碼(Gray Code)?
格雷碼是美國(guó)學(xué)者Frank Gray于1947年提出的一種二進(jìn)制編碼方式,后面這種編碼方式就以他的名字命名。實(shí)際上,格雷碼是有多種編碼形式的。根據(jù)定義,在一組數(shù)的編碼中,若任意兩個(gè)相鄰的代碼只有一位二進(jìn)制數(shù)不同,則稱(chēng)這種編碼為格雷碼。
下表是不同形式的格雷碼:

表中典型格雷碼具有代表性。若不作特別說(shuō)明,格雷碼就是指典型格雷碼(后文將簡(jiǎn)稱(chēng)格雷碼),它可從自然二進(jìn)制碼轉(zhuǎn)換而來(lái)。
好了,現(xiàn)在我問(wèn)你,根據(jù)格雷碼的性質(zhì)你能默寫(xiě)出16個(gè)4bit寬度的格雷碼來(lái)嗎?我想一般是比較難的,因?yàn)閱慰可鲜鲂再|(zhì)很難推導(dǎo)出來(lái)。比如說(shuō),0(0000)可以寫(xiě)出來(lái),1(0001)也可以寫(xiě)出來(lái),2(0011)也可以寫(xiě)出來(lái),但是3就不好寫(xiě)了,因?yàn)楦鶕?jù)只能變化一位的性質(zhì),可以是0111,也可以是0010,那么到底是哪個(gè)呢?如何不是經(jīng)常使用的話,我想是很難判斷的。
所以接下來(lái)就要介紹格雷碼的第二個(gè)性質(zhì)了:當(dāng)?shù)贜位從0變到1的時(shí)候,之后的數(shù)的N-1位會(huì)關(guān)于前半段軸對(duì)稱(chēng),而比N位高的位是相同的。
我們看一下4bit格雷碼的前四位的例子。示意圖如下:
? 當(dāng)0001跳轉(zhuǎn)到下一位時(shí),毋庸置疑的是,第0位會(huì)維持1不變,而第1位會(huì)跳轉(zhuǎn)到1,所以可以據(jù)此畫(huà)出對(duì)稱(chēng)軸
? 高2位(第3、2位)這保持不變
? 低位(該實(shí)例中只有第0位)關(guān)于對(duì)稱(chēng)軸對(duì)稱(chēng)
有了上述三點(diǎn)信息,那么就可以把剩下的2個(gè)格雷碼寫(xiě)出來(lái)了。

4bit格雷碼的前8位示意圖如下(這我就不啰嗦了,你們肯定看得懂):

2、異步FIFO為什么要使用格雷碼?
異步FIFO設(shè)計(jì)最關(guān)鍵的點(diǎn)是什么?答案是“空”和“滿”的判斷?,F(xiàn)在回想一下,我們是如何進(jìn)行狀態(tài)判斷的。很簡(jiǎn)單,分別構(gòu)建讀指針和寫(xiě)指針。寫(xiě)指針總是指向下一個(gè)要寫(xiě)的地址,而讀指針永遠(yuǎn)指向當(dāng)前要讀取的地址。再通過(guò)對(duì)讀、寫(xiě)指針的比較來(lái)判斷空、滿。

如上圖的FIFO深度為8,則其地址位寬應(yīng)該是3(2的三次方等于8)。當(dāng)寫(xiě)指針與讀指針都指向同一個(gè)位置(即相同)時(shí),可能是空狀態(tài),但也可能是滿狀態(tài)(寫(xiě)指針超過(guò)了讀指針一圈)。(這里說(shuō)句題外話,不可能是讀指針超過(guò)寫(xiě)指針一圈,因?yàn)榈x、寫(xiě)指針第一次相等時(shí),就應(yīng)該輸出空狀態(tài),然后停止對(duì)FIFO進(jìn)行讀取操作。)所以,究竟如何判斷FIFO是空還是滿呢?答案是無(wú)法判斷,只能通過(guò)在高位增加一位的方式來(lái)判斷,當(dāng)除了最高位MSB外的其他位都相同,最高位不同時(shí)則表明此時(shí)寫(xiě)指針超過(guò)了讀指針一圈,F(xiàn)IFO被寫(xiě)滿了;當(dāng)除了最高位MSB外的其他位都相同,最高位相同時(shí)則表明此時(shí)寫(xiě)指針等于讀指針,F(xiàn)IFO被讀空了。
這種方法用來(lái)對(duì)同步FIFO進(jìn)行判斷是沒(méi)有問(wèn)題的,因?yàn)橥紽IFO的讀、寫(xiě)指針是同一時(shí)鐘域下的信號(hào),可以直接對(duì)比。但是異步FIFO的讀、寫(xiě)指針是不同時(shí)鐘域下的信號(hào),如果直接對(duì)比則會(huì)有亞穩(wěn)態(tài)的問(wèn)題。為了對(duì)異步FIFO的讀、寫(xiě)指針進(jìn)行判斷,我們首先需要將其同步到統(tǒng)一的時(shí)鐘域下,而這就引發(fā)出了新的問(wèn)題----讀、寫(xiě)指針在大多數(shù)情況下都不是個(gè)單bit信號(hào),而是個(gè)多bit信號(hào)。如果讀、寫(xiě)指針直接使用2進(jìn)制的形式進(jìn)行同步,則難以避免同步過(guò)程中會(huì)出現(xiàn)的多個(gè)bit信號(hào)同時(shí)變化的問(wèn)題。如7(0111)跳轉(zhuǎn)到8(1000),此時(shí)有4個(gè)bit信號(hào)都發(fā)生了變化,如果直接同步,則由于不同信號(hào)之間的延遲(skew),可能導(dǎo)致亞穩(wěn)態(tài)、錯(cuò)采、漏采等等問(wèn)題。
此時(shí)不妨回想下格雷碼的性質(zhì):每相鄰位之間只有一個(gè)bit的變化。FIFO的指針是遞增的,這使得在傳輸遞增的多bit信號(hào)時(shí),格雷碼具有天然的優(yōu)勢(shì)。還是從7到8的例子,若使用格雷碼,則應(yīng)該是7(0100)--8(1100),這樣就只有1個(gè)bit的變化了(最高位),這樣就將多bit信號(hào)的跨時(shí)鐘域轉(zhuǎn)變成了單bit信號(hào)的跨時(shí)鐘域,而單個(gè)bit的跨時(shí)鐘域同步是很好實(shí)現(xiàn)的。
3、讀指針、寫(xiě)指針應(yīng)該被同步到哪個(gè)時(shí)鐘域?
異步FIFO的讀、寫(xiě)指針是不同時(shí)鐘域的信號(hào),那么就不能直接對(duì)比,而是需要將其同步到同一時(shí)鐘域才能進(jìn)行對(duì)比?,F(xiàn)在問(wèn)題來(lái)了?指針應(yīng)該被同步到哪個(gè)時(shí)鐘域?可選項(xiàng)有第三方時(shí)鐘域、讀時(shí)鐘域和寫(xiě)時(shí)鐘域。接下來(lái)不妨逐個(gè)分析。
首先需要說(shuō)明的是,這說(shuō)的同步都是指使用2個(gè)(或者3個(gè),但此類(lèi)情況不多)FF(觸發(fā)器)來(lái)進(jìn)行同步(俗稱(chēng)“打兩拍”),這種同步方式是有延遲的(時(shí)序開(kāi)銷(xiāo),可以看做是兩個(gè)目同步時(shí)鐘周期)。
第三方時(shí)鐘域:不難知道一個(gè)信號(hào)從一個(gè)時(shí)鐘域同步到另一個(gè)時(shí)鐘域(被同步時(shí)鐘域)是需要時(shí)間的(這里僅考慮從滿到快,也就是暫時(shí)不考慮漏采的問(wèn)題),需要的時(shí)間取決于被同步時(shí)鐘域的周期以及需要同步的個(gè)數(shù)。假設(shè)這個(gè)時(shí)間是T,那么經(jīng)過(guò)T時(shí)間后,由于讀寫(xiě)時(shí)鐘不一致,原來(lái)的讀寫(xiě)時(shí)針增加(也可能不變)的量是不一致。比如說(shuō)實(shí)際上讀寫(xiě)時(shí)針都指向4(且最高位相同),那么這種情況實(shí)際上是出現(xiàn)了讀空的情況。但是同步到第三方時(shí)鐘域后,可能寫(xiě)指針成了6,而讀指針變成了8(讀時(shí)鐘比寫(xiě)時(shí)鐘快),那么在這種情況下FIFO就不會(huì)報(bào)“讀空”,從而造成功能錯(cuò)亂。所以該種方法不可取。
同步到寫(xiě)時(shí)鐘域:讀指針同步到寫(xiě)時(shí)鐘域需要時(shí)間T,在經(jīng)過(guò)T時(shí)間后,可能原來(lái)的讀指針會(huì)增加或者不變,也就是說(shuō)同步后的讀指針一定是小于等于原來(lái)的讀指針的。寫(xiě)指針也可能發(fā)生變化,但是寫(xiě)指針本來(lái)就在這個(gè)時(shí)鐘域,所以是不需要同步的,也就意味著進(jìn)行對(duì)比的寫(xiě)指針就是真實(shí)的寫(xiě)指針。
現(xiàn)在來(lái)進(jìn)行寫(xiě)滿的判斷:也就是寫(xiě)指針超過(guò)了同步后的讀指針一圈。但是原來(lái)的讀指針是大于等于同步后的讀指針的,所以實(shí)際上這個(gè)時(shí)候?qū)懼羔樒鋵?shí)是沒(méi)有超過(guò)讀指針一圈的,也就是說(shuō)這種情況是“假寫(xiě)滿”。那么“假寫(xiě)滿”是一種錯(cuò)誤的設(shè)計(jì)嗎?答案是NO。前面我們說(shuō)過(guò)異步FIFO設(shè)計(jì)的關(guān)鍵點(diǎn)是產(chǎn)生合適的“寫(xiě)滿”和“讀空”信號(hào),那么何謂“合適”?該報(bào)的時(shí)候沒(méi)報(bào)算合適嗎?當(dāng)然不算合適。不該報(bào)的時(shí)候報(bào)了算不算合適?答案是算??梢韵胂笠幌?,假設(shè)一個(gè)深度為100的FIFO,在寫(xiě)到第98個(gè)數(shù)據(jù)的時(shí)候就報(bào)了“寫(xiě)滿”,會(huì)引起什么后果?答案是不會(huì)造成功能錯(cuò)誤,只會(huì)造成性能損失(2%),大不了FIFO的深度我少用一點(diǎn)點(diǎn)就是的。事實(shí)上這還可以算是某種程度上的保守設(shè)計(jì)(安全)。
接著進(jìn)行讀空的判斷:也就是同步后的讀指針追上了寫(xiě)指針。但是原來(lái)的讀指針是大于等于同步后的讀指針的,所以實(shí)際上這個(gè)時(shí)候讀指針實(shí)際上是超過(guò)了寫(xiě)指針。這種情況意味著已經(jīng)發(fā)生了“讀空”,卻仍然有錯(cuò)誤數(shù)據(jù)讀出。所以這種情況就造成了FIFO的功能錯(cuò)誤。
同步到讀時(shí)鐘域:寫(xiě)指針同步到讀時(shí)鐘域需要時(shí)間T,在經(jīng)過(guò)T時(shí)間后,可能原來(lái)的讀指針會(huì)增加或者不變,也就是說(shuō)同步后的寫(xiě)指針一定是小于等于原來(lái)的寫(xiě)指針的。讀指針也可能發(fā)生變化,但是讀指針本來(lái)就在這個(gè)時(shí)鐘域,所以是不需要同步的,也就意味著進(jìn)行對(duì)比的讀指針就是真實(shí)的讀指針。
現(xiàn)在來(lái)進(jìn)行寫(xiě)滿的判斷:也就是同步后的寫(xiě)指針超過(guò)了讀指針一圈。但是原來(lái)的寫(xiě)指針是大于等于同步后的寫(xiě)指針的,所以實(shí)際上這個(gè)時(shí)候?qū)懼羔樢呀?jīng)超過(guò)了讀指針不止一圈,這種情況意味著已經(jīng)發(fā)生了“寫(xiě)滿”,卻仍然數(shù)據(jù)被覆蓋寫(xiě)入。所以這種情況就造成了FIFO的功能錯(cuò)誤。
接著進(jìn)行讀空的判斷:也就是讀指針追上了同步后的指針。但是原來(lái)的寫(xiě)指針是大于等于同步后的寫(xiě)指針的,所以實(shí)際上這個(gè)時(shí)候讀指針其實(shí)還沒(méi)有追上寫(xiě)指針,也就是說(shuō)這種情況是“假讀空”。那么“假讀空”是一種錯(cuò)誤的設(shè)計(jì)嗎?答案是NO。前面我們說(shuō)過(guò)異步FIFO設(shè)計(jì)的關(guān)鍵點(diǎn)是產(chǎn)生合適的“寫(xiě)滿”和“讀空”信號(hào),那么何謂“合適”?該報(bào)的時(shí)候沒(méi)報(bào)算合適嗎?當(dāng)然不算合適。不該報(bào)的時(shí)候報(bào)了算不算合適?答案是算。可以想象一下,假設(shè)某個(gè)FIFO,在讀到還剩2個(gè)數(shù)據(jù)的時(shí)候就報(bào)了“讀空”,會(huì)引起什么后果?答案是不會(huì)造成功能錯(cuò)誤,只會(huì)造成性能損失(2%),大不了我先不讀了,等數(shù)據(jù)多了再讀就是的。事實(shí)上這還可以算是某種程度上的保守設(shè)計(jì)(安全)。
現(xiàn)在可以總結(jié)一下:
? “寫(xiě)滿”的判斷:需要將讀指針同步到寫(xiě)時(shí)鐘域,再與寫(xiě)指針判斷
? “讀空”的判斷:需要將寫(xiě)指針同步到讀時(shí)鐘域,再與讀指針判斷
假讀空示意如下:

假寫(xiě)滿示意如下:

4、如何判斷異步FIFO的空和滿?
在同步FIFO的設(shè)計(jì)中,我們把讀、寫(xiě)指針的位寬拓寬了1bit,目的是區(qū)分原來(lái)的讀、寫(xiě)指針相等時(shí)判斷空、滿的問(wèn)題。同步FIFO的指針使用的是2進(jìn)制碼的形式,而異步FIFO為了減少多bit信號(hào)跨時(shí)鐘域傳輸?shù)膩喎€(wěn)態(tài)問(wèn)題,采用的是格雷碼形式的指針,那么格雷碼形式的指針應(yīng)該如何對(duì)比來(lái)判斷空和滿?
首先要說(shuō)明的是,將格雷碼轉(zhuǎn)換成2進(jìn)制再進(jìn)行對(duì)比是一種很好的辦法,但是會(huì)消耗多的組合邏輯資源,所以我們暫時(shí)不討論。

先觀察上圖,假定我們要設(shè)計(jì)的FIFO深度為8,那么指針寬度是4,因?yàn)閷挾葹?時(shí)無(wú)法區(qū)分空、滿。
空的判斷很好判斷,只要讀寫(xiě)指針?biāo)形蝗恳恢?,則說(shuō)明此時(shí)是空狀態(tài)。
滿的判斷復(fù)雜一點(diǎn),假設(shè)采用同步FIFO的判斷方法----最高位不同,其他位一致。我們用實(shí)際的數(shù)值來(lái)看看是什么情況:當(dāng)讀指針的值為0100,則說(shuō)明此時(shí)讀指針指向最高的空間7,那么若是FIFO滿了,則寫(xiě)指針應(yīng)該是1100,那么1100對(duì)應(yīng)的二進(jìn)制是多少呢?是8。那么讀寫(xiě)指針、一個(gè)指向7,另一個(gè)卻指向8,這是滿?顯然不是。
如果真的是滿的話,寫(xiě)指針應(yīng)該是多少?應(yīng)該是15,也就是1000,此時(shí)寫(xiě)指針是超過(guò)讀指針8,也就是一圈的。那么0100和1000有什么聯(lián)系?很顯然,高兩位相反,低位相同。這種規(guī)律的形成原因是我們之前提到的,格雷碼的變化都關(guān)于某個(gè)對(duì)稱(chēng)軸對(duì)稱(chēng)。
總結(jié):
? 當(dāng)最高位和次高位相同,其余位相同認(rèn)為是讀空
? 當(dāng)最高位和次高位不同,其余位相同認(rèn)為是寫(xiě)滿
5、空和滿的判斷是準(zhǔn)確的嗎?
在第4點(diǎn)我們知道了----將讀指針同步到寫(xiě)時(shí)鐘域來(lái)判斷滿;將寫(xiě)指針同步到讀時(shí)鐘域來(lái)判斷空。既然是異步FIFO,那么讀寫(xiě)時(shí)鐘域的信號(hào)是不一致的,其中一個(gè)的頻率快,另一個(gè)的頻率這慢。那么在兩次同步過(guò)程中,一定是一次慢時(shí)鐘采快時(shí)鐘和一次快時(shí)鐘采慢時(shí)鐘??鞎r(shí)鐘采慢時(shí)鐘是不會(huì)有問(wèn)題的,因?yàn)檫@符合采樣定理。但是慢時(shí)鐘采快時(shí)鐘則會(huì)有問(wèn)題,因?yàn)椴蓸舆^(guò)程不符合采樣定理。
那么會(huì)造成什么問(wèn)題?答案是漏采。某些數(shù)值可能會(huì)被漏掉。例如原本是連續(xù)的0--1--2---3的信號(hào),從快時(shí)鐘同步到慢時(shí)鐘后,就變成了離散的0--3,其中的1、2被漏掉了。那么這樣一種現(xiàn)象會(huì)導(dǎo)致空、滿的判斷是準(zhǔn)確的嗎?答案是不準(zhǔn)確,但沒(méi)關(guān)系。
設(shè)想讀慢寫(xiě)快與讀快寫(xiě)慢兩種情況:
讀慢寫(xiě)快:
進(jìn)行寫(xiě)滿判斷的時(shí)候需要將讀指針同步到寫(xiě)時(shí)鐘域,因?yàn)樽x慢寫(xiě)快,所以不會(huì)有讀指針遺漏,同步消耗時(shí)鐘周期,所以同步后的讀指針滯后(小于等于)當(dāng)前讀地址,所以可能寫(xiě)滿會(huì)提前產(chǎn)生,并非真寫(xiě)滿。
進(jìn)行讀空判斷的時(shí)候需要將寫(xiě)指針同步到讀指針 ,因?yàn)樽x慢寫(xiě)快,所以當(dāng)讀時(shí)鐘同步寫(xiě)指針的時(shí)候,必然會(huì)漏掉一部分寫(xiě)指針,我們不用關(guān)心那到底會(huì)漏掉哪些寫(xiě)指針,我們?cè)诤醯氖锹┑舻闹羔槙?huì)對(duì)FIFO的讀空產(chǎn)生影響嗎?比如寫(xiě)指針從0寫(xiě)到10,期間讀時(shí)鐘域只同步捕捉到了3、5、8這三個(gè)寫(xiě)指針而漏掉了其他指針。當(dāng)同步到8這個(gè)寫(xiě)指針時(shí),真實(shí)的寫(xiě)指針可能已經(jīng)寫(xiě)到10 ,相當(dāng)于在讀時(shí)鐘域還沒(méi)來(lái)得及覺(jué)察的情況下,寫(xiě)時(shí)鐘域可能寫(xiě)了數(shù)據(jù)到FIFO去,這樣在判斷它是不是空的時(shí)候會(huì)出現(xiàn)不是真正空的情況,漏掉的指針也沒(méi)有對(duì)FIFO的邏輯操作產(chǎn)生影響。
讀快寫(xiě)慢:
進(jìn)行讀空判斷的時(shí)候需要將寫(xiě)指針同步到讀指針 ,因?yàn)樽x快寫(xiě)慢,所以不會(huì)有寫(xiě)指針遺漏,同步消耗時(shí)鐘周期,所以同步后的寫(xiě)指針滯后(小于等于)當(dāng)前寫(xiě)地址,所以可能讀空會(huì)提前產(chǎn)生,并非真讀空。
進(jìn)行寫(xiě)滿判斷的時(shí)候需要將讀指針同步到寫(xiě)時(shí)鐘域,因?yàn)樽x快寫(xiě)慢,所以當(dāng)寫(xiě)時(shí)鐘同步讀指針的時(shí)候,必然會(huì)漏掉一部分讀指針,我們不用關(guān)心那到底會(huì)漏掉哪些讀指針,我們?cè)诤醯氖锹┑舻闹羔槙?huì)對(duì)FIFO的寫(xiě)滿產(chǎn)生影響嗎?比如讀指針從0讀到10,期間寫(xiě)時(shí)鐘域只同步捕捉到了3、5、8這三個(gè)讀指針而漏掉了其他指針。當(dāng)同步到8這個(gè)讀指針時(shí),真實(shí)的讀指針可能已經(jīng)讀到10 ,相當(dāng)于在寫(xiě)時(shí)鐘域還沒(méi)來(lái)得及覺(jué)察的情況下,讀時(shí)鐘域可能從FIFO讀了數(shù)據(jù)出來(lái),這樣在判斷它是不是滿的時(shí)候會(huì)出現(xiàn)不是真正滿的情況,漏掉的指針也沒(méi)有對(duì)FIFO的邏輯操作產(chǎn)生影響。
現(xiàn)在我們會(huì)發(fā)現(xiàn),所謂的空滿信號(hào)實(shí)際上是不準(zhǔn)確的,在還沒(méi)有空、滿的時(shí)鐘就已經(jīng)輸出了空滿信號(hào),這樣的空滿信號(hào)一般稱(chēng)為假空、假滿。假空、假滿信號(hào)本質(zhì)上是一種保守設(shè)計(jì),想象一下,一個(gè)深度為16的異步FIFO,在其寫(xiě)入14個(gè)數(shù)據(jù)時(shí),即輸出了寫(xiě)滿(假滿)標(biāo)志,這會(huì)對(duì)我們的設(shè)計(jì)造成影響嗎?會(huì),會(huì)削弱我們的效率,我們實(shí)際使用的FIFO深度成了14,但是會(huì)使得我們的設(shè)計(jì)產(chǎn)生錯(cuò)誤嗎?顯然不會(huì)。同樣的,在FIFO深度仍有2時(shí)即輸出了讀空(假空)標(biāo)志,也不會(huì)使得我們的設(shè)計(jì)出錯(cuò),但是會(huì)降低效率,因?yàn)槲覀兪褂玫腇IFO深度又少了2。
6、既然有假滿、假空,那么有沒(méi)有真滿、真空?
還真有,但是沒(méi)意義。既然我們可以將讀指針同步到寫(xiě)時(shí)鐘域來(lái)判斷假滿;將寫(xiě)指針同步到讀時(shí)鐘域來(lái)判斷假空。那么對(duì)應(yīng)地,可以讀指針同步到寫(xiě)時(shí)鐘域來(lái)判斷空;將寫(xiě)指針同步到讀時(shí)鐘域來(lái)判斷滿。
在寫(xiě)時(shí)鐘域判斷空:
讀指針被同步過(guò)來(lái)的信號(hào)(同步后讀指針)是滯后于真實(shí)讀指針的信號(hào),當(dāng)同步后讀指針等于寫(xiě)指針時(shí),真實(shí)讀指針實(shí)際上早就等于寫(xiě)指針了,也就是說(shuō)此時(shí)的空一定是空,甚至已經(jīng)空了一段時(shí)間了。這樣的空標(biāo)志顯然是沒(méi)有使用意義的,因?yàn)闀?huì)造成對(duì)FIFO的過(guò)讀操作,你來(lái)來(lái)回回讀個(gè)空FIFO有什么意義呢?也就是說(shuō)真空能實(shí)現(xiàn),但是沒(méi)實(shí)際使用意義。
在讀時(shí)鐘域判斷滿:
寫(xiě)指針被同步過(guò)來(lái)的信號(hào)(同步后寫(xiě)指針)是滯后于真實(shí)寫(xiě)指針的信號(hào),但同步后寫(xiě)指針超過(guò)讀指針一圈時(shí),真實(shí)寫(xiě)指針實(shí)際上早就超過(guò)讀指針一圈了,也就是說(shuō)此時(shí)的滿一定是滿,甚至已經(jīng)滿了一段時(shí)間了。這樣的滿標(biāo)志顯然是沒(méi)有使用意義的,因?yàn)闀?huì)造成對(duì)FIFO的過(guò)寫(xiě)操作,你來(lái)來(lái)回回寫(xiě)個(gè)滿FIFO有什么意義呢?也就是說(shuō)真滿也能實(shí)現(xiàn),但是同樣沒(méi)實(shí)際使用意義。
7、非2次冪深度的FIFO如何設(shè)計(jì)?
在第1點(diǎn)關(guān)于格雷碼的性質(zhì)中,我們闡述了:
? 在一組數(shù)的編碼中,若任意兩個(gè)相鄰的代碼只有一位二進(jìn)制數(shù)不同,則稱(chēng)這種編碼為格雷碼
? 當(dāng)?shù)贜位從0變到1的時(shí)候,之后的數(shù)的N-1位會(huì)關(guān)于前半段軸對(duì)稱(chēng),而比N位高的位是相同的。
由這兩點(diǎn),我們發(fā)現(xiàn)格雷碼都可以關(guān)于某條對(duì)稱(chēng)軸對(duì)稱(chēng)。所以只有當(dāng)FIFO深度為2的冪次方時(shí),才能做到格雷碼繞一圈后,回到初始位置仍然只有1bit變化,如15(1000)----0(0000)。當(dāng)FIFO深度不為2的冪次方時(shí),顯然從最尾端跳轉(zhuǎn)到開(kāi)頭端,變化的就不止一個(gè)bit了。比如FIFO深度為7,顯然,從13(1011)----0(0000),變化了可不止1bit。這樣的話在這一次跳變就失去了格雷碼存在的意義了,所以得想點(diǎn)其他辦法解決。
前面說(shuō)過(guò),格雷碼相鄰每位只變化1bit,而且關(guān)于中軸對(duì)稱(chēng)的。那么我們可以這樣編碼:針對(duì)深度為7的FIFO,從1(0001)開(kāi)始,一直到(14個(gè)數(shù)表示7深度,高位區(qū)分狀態(tài))14(1001),1(0001)與14(1001)是關(guān)于中軸對(duì)稱(chēng)的(高位為變化位),所以也只有1bit的跳變。同樣的如果深度為6的FIFO,就從2(0011)開(kāi)始,到13(1011),同樣只跳變1bit。

空標(biāo)志只用判斷讀、寫(xiě)指針是否全部相等即可。但是滿標(biāo)志就不能用“高兩位相反,其他位相同來(lái)判斷了”,需要找其他規(guī)律了。從這里可以看出,格雷碼作為一種無(wú)權(quán)碼,在比較和運(yùn)算等方面不如有權(quán)碼二進(jìn)制靈活。所以,咱要不還是轉(zhuǎn)回二進(jìn)制再比較吧。
不管你設(shè)計(jì)FIFO用RAM還是直接調(diào)用IP也好,最終實(shí)現(xiàn)都是用的Block RAM資源,其生成的位寬肯定是2的冪次。所以啊,不用也是浪費(fèi)啊。