什么是 FIFO ?
FIFO 是英文 First In First Out 的縮寫,是一種先進(jìn)先出的數(shù)據(jù)緩存器,他與普通存儲器的區(qū)別是沒有外部讀寫地址線,這樣使用起來非常簡單,但缺點(diǎn)就是只能順序?qū)懭霐?shù)據(jù),順序的讀出數(shù)據(jù),其數(shù)據(jù)地址由內(nèi)部讀寫指針自動加 1 完成,不能像普通存儲器那樣可以由地址線決定讀取或?qū)懭肽硞€指定的地址。
什么情況下用 FIFO ?
FIFO 一般用于不同時鐘域之間的數(shù)據(jù)傳輸,比如 FIFO 的一端時 AD 數(shù)據(jù)采集,另一端時計算機(jī)的PCI總線,假設(shè)其AD采集的速率為16位 100K SPS,那么每秒的數(shù)據(jù)量為100K×16bit=1.6Mbps, 而 PCI 總線的速度為 33MHz ,總線寬度 32bit, 其最大傳輸速率為 1056Mbps, 在兩個不同的時鐘域間就可以采用 FIFO 來作為數(shù)據(jù)緩沖。另外對于不同寬度的數(shù)據(jù)接口也可以用 FIFO ,例如單片機(jī)位 8 位數(shù)據(jù)輸出,而 DSP 可能是 16 位數(shù)據(jù)輸入,在單片機(jī)與 DSP 連接時就可以使用 FIFO 來達(dá)到數(shù)據(jù)匹配的目的。
FIFO 的一些重要參數(shù)
FIFO 的寬度:也就是英文資料里常看到的 THE WIDTH ,它指的是 FIFO 一次讀寫操作的數(shù)據(jù)位,就像 MCU 有 8 位和 16 位, ARM 32 位等等, FIFO 的寬度在單片成品 IC 中是固定的,也有可選擇的,如果用 FPGA 自己實(shí)現(xiàn)一個 FIFO ,其數(shù)據(jù)位,也就是寬度是可以自己定義的。
FIFO 的深度: THE DEEPTH ,它指的是 FIFO 可以存儲多少個 N 位的數(shù)據(jù)(如果寬度為 N )。如一個 8 位的 FIFO ,若深度為 8 ,它可以存儲 8 個 8 位的數(shù)據(jù),深度為 12 ,就可以存儲 12 個 8 位的數(shù)據(jù), FIFO 的深度可大可小,個人認(rèn)為 FIFO 深度的計算并無一個固定的公式。在 FIFO 實(shí)際工作中,其數(shù)據(jù)的滿 / 空標(biāo)志可以控制數(shù)據(jù)的繼續(xù)寫入或讀出。在一個具體的應(yīng)用中也不可能由一些參數(shù)算數(shù)精確的所需 FIFO 深度為多少,這在寫速度大于讀速度的理想狀態(tài)下是可行的,但在實(shí)際中用到的 FIFO 深度往往要大于計算值。一般來說根據(jù)電路的具體情況,在兼顧系統(tǒng)性能和 FIFO 成本的情況下估算一個大概的寬度和深度就可以了。而對于寫速度慢于讀速度的應(yīng)用, FIFO 的深度要根據(jù)讀出的數(shù)據(jù)結(jié)構(gòu)和讀出數(shù)據(jù)的由那些具體的要求來確定。
滿標(biāo)志: FIFO 已滿或?qū)⒁獫M時由 FIFO 的狀態(tài)電路送出的一個信號,以阻止 FIFO 的寫操作繼續(xù)向 FIFO 中寫數(shù)據(jù)而造成 溢出 (overflow)。
空標(biāo)志: FIFO 已空或?qū)⒁諘r由 FIFO 的狀態(tài)電路送出的一個信號,以阻止 FIFO 的讀操作繼續(xù)從 FIFO 中讀出數(shù)據(jù)而造成無效數(shù)據(jù)的讀出( underflow )。
讀時鐘:讀操作所遵循的時鐘,在每個時鐘沿來臨時讀數(shù)據(jù)。
寫時鐘:寫操作所遵循的時鐘,在每個時鐘沿來臨時寫數(shù)據(jù)。
讀指針:指向下一個讀出地址。讀完后自動加 1 。
寫指針:指向下一個要寫入的地址的,寫完自動加 1 。
讀寫指針其實(shí)就是讀寫的地址,只不過這個地址不能任意選擇,而是連續(xù)的。
FIFO 的分類
根均 FIFO 工作的時鐘域,可以將 FIFO 分為同步 FIFO 和異步 FIFO 。同步 FIFO 是指讀時鐘和寫時鐘為同一個時鐘。在時鐘沿來臨時同時發(fā)生讀寫操作。異步 FIFO 是指讀寫時鐘不一致,讀寫時鐘是互相獨(dú)立的。
FIFO 設(shè)計的難點(diǎn)
FIFO 設(shè)計的難點(diǎn)在于怎樣判斷 FIFO 的空 / 滿狀態(tài)。為了保證數(shù)據(jù)正確的寫入或讀出,而不發(fā)生溢出或讀空的狀態(tài)出現(xiàn),必須保證 FIFO 在滿的情況下,不能進(jìn)行寫操作。在空的狀態(tài)下不能進(jìn)行讀操作。怎樣判斷 FIFO 的滿 / 空就成了 FIFO 設(shè)計的核心問題。由于同步 FIFO 幾乎很少用到,這里只描述異步 FIFO 的空 / 滿標(biāo)志產(chǎn)生問題。
在用到觸發(fā)器的設(shè)計中,不可避免的會遇到 亞穩(wěn)態(tài) 的問題(關(guān)于亞穩(wěn)態(tài)這里不作介紹,可查看相關(guān)資料)。在涉及到觸發(fā)器的電路中,亞穩(wěn)態(tài)無法徹底消除,只能想辦法將其發(fā)生的概率將到最低。其中的一個方法就是使用格雷碼。格雷碼在相鄰的兩個碼元之間只有一位變換(二進(jìn)制碼在很多情況下是很多碼元在同時變化)。這就會避免計數(shù)器與時鐘同步的時候發(fā)生亞穩(wěn)態(tài)現(xiàn)象。但是格雷碼有個缺點(diǎn)就是只能定義2^n的深度,而不能像二進(jìn)制碼那樣隨意的定義FIFO的深度,因?yàn)楦窭状a必須循環(huán)一個2^n,否則就不能保證兩個相鄰碼元之間相差一位的條件,因此也就不是真正的各雷碼了。第二就是使用冗余的觸發(fā)器,假設(shè)一個觸發(fā)器發(fā)生亞穩(wěn)態(tài)的概率為P,那么兩個及聯(lián)的觸發(fā)器發(fā)生亞穩(wěn)態(tài)的概率就為P的平方。但這回導(dǎo)致延時的增加。亞穩(wěn)態(tài)的發(fā)生會使得FIFO出現(xiàn)錯誤,讀/寫時鐘采樣的地址指針會與真實(shí)的值之間不同,這就導(dǎo)致寫入或讀出的地址錯誤。由于考慮延時的作用,空/滿標(biāo)志的產(chǎn)生并不一定出現(xiàn)在FIFO真的空/滿時才出現(xiàn)。可能FIFO還未空/滿時就出現(xiàn)了空/滿標(biāo)志。這并沒有什么不好,只要保證FIFO不出現(xiàn)overflow or underflow 就OK了。
很多關(guān)于 FIFO 的文章其實(shí)討論的都是空 / 滿標(biāo)志的不同算法問題。
在 Vijay A. Nebhrajani 的《異步 FIFO 結(jié)構(gòu)》一文中,作者提出了兩個關(guān)于 FIFO 空 / 滿標(biāo)志的算法。
第一個算法:構(gòu)造一個指針寬度為 N+1 ,深度為 2^N 字節(jié)的 FIFO (為便方比較將格雷碼指針轉(zhuǎn)換為二進(jìn)制指針)。當(dāng)指針的二進(jìn)制碼中最高位不一致而其它 N 位都相等時, FIFO 為滿(在 Clifford E. Cummings 的文章中以格雷碼表示是前兩位均不相同,而后兩位 LSB 相同為滿,這與換成二進(jìn)制表示的 MSB 不同其他相同為滿是一樣的)。當(dāng)指針完全相等時, FIFO 為空。這也許不容易看出,舉個例子說明一下:一個深度為 8 字節(jié)的 FIFO 怎樣工作(使用已轉(zhuǎn)換為 二進(jìn)制 的指針)。FIFO_WIDTH=8,F(xiàn)IFO_DEPTH= 2^N = 8,N = 3,指針寬度為N+1=4。起初rd_ptr_bin和wr_ptr_bin均為“0000”。此時FIFO中寫入8個字節(jié)的數(shù)據(jù)。wr_ptr_bin =“1000”,rd_ptr_bin=“0000”。當(dāng)然,這就是滿條件。現(xiàn)在,假設(shè)執(zhí)行了8次的讀操作,使得rd_ptr_bin =“1000”,這就是空條件。另外的8次寫操作將使wr_ptr_bin 等于“0000”,但rd_ptr_bin 仍然等于“1000”,因此FIFO為滿條件。
顯然起始指針無需為“ 0000 ”。假設(shè)它為“ 0100 ”,并且 FIFO 為空,那么 8 個字節(jié)會使 wr_ptr_bin = “ 1100 ”, , rd_ptr_bin 仍然為“ 0100 ”。這又說明 FIFO 為滿。
在 Vijay A. Nebhrajani 的這篇《異步 FIFO 結(jié)構(gòu)》文章中說明了怎樣運(yùn)用格雷碼來設(shè)置空滿的條件,但沒有說清為什么深度為 8 的 FIFO 其讀寫指針要用 3+1 位的格雷碼來實(shí)現(xiàn),而 3+1 位的格雷碼可以表示 16 位的深度,而真實(shí)的 FIFO 只有 8 位,這是怎么回事?而這個問題在 Clifford E. Cummings 的文章中得以解釋。三位格雷碼可表示 8 位的深度,若在加一位最為 MSB ,則這一位加其他三位組成的格雷碼并不代表新的地址,也就是說格雷碼的 0100 表示表示 7 ,而 1100 仍然表示 7 ,只不過格雷碼在經(jīng)過一個以 0 位 MSB 的循環(huán)后進(jìn)入一個以 1 為 MSB 的循環(huán),然后又進(jìn)入一個以 0 位 MSB 的循環(huán),其他的三位碼仍然是格雷碼,但這就帶來一個問題,在 0100 的循環(huán)完成后,進(jìn)入 1000 ,他們之間有兩位發(fā)生了變換,而不是 1 位,所以增加一位 MSB 的做法使得該碼在兩處: 0100~1000 , 1100~0000 有兩位碼元發(fā)生變化,故該碼以不是真正的格雷碼。增加的 MSB 是為了實(shí)現(xiàn)空滿標(biāo)志的計算。 Vijay A. Nebhrajani 的文章用格雷碼轉(zhuǎn)二進(jìn)制,再轉(zhuǎn)格雷碼的情況下提出空滿條件,僅過兩次轉(zhuǎn)換,而 Clifford E. Cummings 的文章中直接在格雷碼條件下得出空滿條件。其實(shí)二者是一樣的,只是實(shí)現(xiàn)方式不同罷了。
第二種算法: 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 結(jié)構(gòu)》第三部分的文章中也提到了一種方法,那就是方向標(biāo)志與門限。設(shè)定了 FIFO 容量的 75% 作為上限,設(shè)定 FIFO 容量的 25% 為下限。當(dāng)方向標(biāo)志超過門限便輸出滿 / 空標(biāo)志,這與 Clifford E. Cummings 的文章中提到的 STYLE #2 可謂是異曲同工。他們都屬于保守的空滿判斷。其實(shí)這時輸出空滿標(biāo)志 FIFO 并不一定真的空 / 滿。
說到此,我們已經(jīng)清楚地看到, FIFO 設(shè)計最關(guān)鍵的就是產(chǎn)生空 / 滿標(biāo)志的算法的不同產(chǎn)生了不同的 FIFO 。但無論是精確的空滿還是保守的空滿都是為了保證 FIFO 工作的可靠。
源文檔 < http://baike.baidu.com/view/132385.htm >
FIFO ( First In First Out) 簡單說就是指先進(jìn)先出。由于微電子技術(shù)的飛速發(fā)展,新一代 FIFO 芯片容量越來越大,體積越來越小,價格越來越便宜。作為一種新型大規(guī)模集成電路, FIFO 芯片以其靈活、方便、高效的特性,逐漸在高速數(shù)據(jù)采集、高速數(shù)據(jù)處理、高速數(shù)據(jù)傳輸以及多機(jī)處理系統(tǒng)中得到越來越廣泛的應(yīng)用。
FIFO 存儲器簡介
在系統(tǒng)設(shè)計中,以增加 數(shù)據(jù) 傳輸率、處理大量數(shù)據(jù)流、匹配具有不同傳輸率的系統(tǒng)為目的而廣泛使用 FIFO 存儲器,從而提高了系統(tǒng)性能。FIFO存儲器是一個先入先出的雙口緩沖器,即第一個進(jìn)入其內(nèi)的數(shù)據(jù)第一個被移出,其中一個 存儲器 的輸入口,另一個口是存儲器的輸出口。對于單片F(xiàn)IFO來說,主要有兩種結(jié)構(gòu):觸發(fā)導(dǎo)向結(jié)構(gòu)和零導(dǎo)向傳輸結(jié)構(gòu)。觸發(fā)導(dǎo)向傳輸結(jié)構(gòu)的FIFO是由寄存器陣列構(gòu)成的,零導(dǎo)向傳輸結(jié)構(gòu)的FIFO是由具有讀和寫地址指針的雙口RAM構(gòu)成。
FIFO 存儲器是系統(tǒng)的緩沖環(huán)節(jié),如果沒有 FIFO 存儲器,整個系統(tǒng)就不可能正常工作,它主要有幾方面的功能:
1 )對連續(xù)的數(shù)據(jù)流進(jìn)行緩存,防止在進(jìn)機(jī)和存儲操作時丟失數(shù)據(jù);
2 )數(shù)據(jù)集中起來進(jìn)行進(jìn)機(jī)和存儲,可避免頻繁的總線操作,減輕 CPU 的負(fù)擔(dān);
3 )允許系統(tǒng)進(jìn)行 DMA 操作,提高數(shù)據(jù)的傳輸速度。這是至關(guān)重要的一點(diǎn),如果不采用 DMA 操作,數(shù)據(jù)傳輸將達(dá)不到傳輸要求,而且大大增加 CPU 的負(fù)擔(dān),無法同時完成數(shù)據(jù)的存儲工作。
因此,選擇合適的存儲芯片對于提高系統(tǒng)性能很重要,在以往的設(shè)計中經(jīng)常采用的是“乒乓型”存儲方式,這種方式就是采用兩片存儲器,數(shù)據(jù)首先進(jìn)入其中一片,當(dāng)數(shù)據(jù)滿時再讓數(shù)據(jù)進(jìn)入第二片存儲器,同時通過邏輯控制,將第一片存儲器中的數(shù)據(jù)取走,以此類推,兩片輪流對數(shù)據(jù)進(jìn)行緩存。這種方式有著較明顯的缺點(diǎn),首先是控制復(fù)雜,要有專門的邏輯來維護(hù)這種輪流機(jī)制 ; 其次,數(shù)據(jù)流的流向要不斷變化,限制了數(shù)據(jù)流的速率,還容易產(chǎn)生干擾。從數(shù)據(jù)傳輸上說,緩存芯片容量越大,對后續(xù)時序要求就越低,可減少總線操作的頻次;但從數(shù)據(jù)存儲上說,就意味著需要開辟更大的內(nèi)存空間來進(jìn)行進(jìn)行緩沖,會增加計算機(jī)的內(nèi)存開銷,而且容量越大,成本也越高。因此,在綜合考慮系統(tǒng)性能和成本的基礎(chǔ)上,選擇滿足系統(tǒng)需要的芯片即可。
FIFO 是 First In/First - Out 的縮寫,是先入先出的意思。 FIFO 存儲器分為寫入專用區(qū)和讀取專用區(qū)。讀操作與寫操作可以異步進(jìn)行,寫入?yún)^(qū)上寫入的數(shù)據(jù)按照寫入的順序從讀取端的區(qū)中讀出,類似于吸收寫入端與讀出端速度差的一種緩沖器。計算機(jī)的串口,一般也都具有 FIFO 緩沖器(不是單一的 FIFO 存儲器,而是嵌入在設(shè)備內(nèi)部)。
FIFO 存儲器的連接模式如圖所示。在 FIFO 存儲器而不是地址總線上附加了表示內(nèi)部緩沖器狀態(tài)( Buffer Full ,緩沖器已滿; Buffer Empty ,緩沖器為空)的狀態(tài)引腳,連接于 FIFO 的雙方利用該狀態(tài)進(jìn)行操作的控制。另外,還設(shè)計了在接通電源及復(fù)位( Reset )或由于操作中的某些異常等原因而重新初始化(無數(shù)據(jù)狀態(tài)) FIFO 的復(fù)位引腳,這可以說是 FIFO 存儲器的特點(diǎn)。
深 入了解 FIFO
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
