什么是 FIFO ?
FIFO 是英文 First In First Out 的縮寫,是一種先進先出的數據緩存器,他與普通存儲器的區別是沒有外部讀寫地址線,這樣使用起來非常簡單,但缺點就是只能順序寫入數據,順序的讀出數據,其數據地址由內部讀寫指針自動加 1 完成,不能像普通存儲器那樣可以由地址線決定讀取或寫入某個指定的地址。
什么情況下用 FIFO ?
FIFO 一般用于不同時鐘域之間的數據傳輸,比如 FIFO 的一端時 AD 數據采集,另一端時計算機的PCI總線,假設其AD采集的速率為16位 100K SPS,那么每秒的數據量為100K×16bit=1.6Mbps, 而 PCI 總線的速度為 33MHz ,總線寬度 32bit, 其最大傳輸速率為 1056Mbps, 在兩個不同的時鐘域間就可以采用 FIFO 來作為數據緩沖。另外對于不同寬度的數據接口也可以用 FIFO ,例如單片機位 8 位數據輸出,而 DSP 可能是 16 位數據輸入,在單片機與 DSP 連接時就可以使用 FIFO 來達到數據匹配的目的。
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 。
讀寫指針其實就是讀寫的地址,只不過這個地址不能任意選擇,而是連續的。
FIFO 的分類
根均 FIFO 工作的時鐘域,可以將 FIFO 分為同步 FIFO 和異步 FIFO 。同步 FIFO 是指讀時鐘和寫時鐘為同一個時鐘。在時鐘沿來臨時同時發生讀寫操作。異步 FIFO 是指讀寫時鐘不一致,讀寫時鐘是互相獨立的。
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 工作的可靠。
源文檔 < http://baike.baidu.com/view/132385.htm >
FIFO ( First In First Out) 簡單說就是指先進先出。由于微電子技術的飛速發展,新一代 FIFO 芯片容量越來越大,體積越來越小,價格越來越便宜。作為一種新型大規模集成電路, FIFO 芯片以其靈活、方便、高效的特性,逐漸在高速數據采集、高速數據處理、高速數據傳輸以及多機處理系統中得到越來越廣泛的應用。
FIFO 存儲器簡介
在系統設計中,以增加 數據 傳輸率、處理大量數據流、匹配具有不同傳輸率的系統為目的而廣泛使用 FIFO 存儲器,從而提高了系統性能。FIFO存儲器是一個先入先出的雙口緩沖器,即第一個進入其內的數據第一個被移出,其中一個 存儲器 的輸入口,另一個口是存儲器的輸出口。對于單片FIFO來說,主要有兩種結構:觸發導向結構和零導向傳輸結構。觸發導向傳輸結構的FIFO是由寄存器陣列構成的,零導向傳輸結構的FIFO是由具有讀和寫地址指針的雙口RAM構成。
FIFO 存儲器是系統的緩沖環節,如果沒有 FIFO 存儲器,整個系統就不可能正常工作,它主要有幾方面的功能:
1 )對連續的數據流進行緩存,防止在進機和存儲操作時丟失數據;
2 )數據集中起來進行進機和存儲,可避免頻繁的總線操作,減輕 CPU 的負擔;
3 )允許系統進行 DMA 操作,提高數據的傳輸速度。這是至關重要的一點,如果不采用 DMA 操作,數據傳輸將達不到傳輸要求,而且大大增加 CPU 的負擔,無法同時完成數據的存儲工作。
因此,選擇合適的存儲芯片對于提高系統性能很重要,在以往的設計中經常采用的是“乒乓型”存儲方式,這種方式就是采用兩片存儲器,數據首先進入其中一片,當數據滿時再讓數據進入第二片存儲器,同時通過邏輯控制,將第一片存儲器中的數據取走,以此類推,兩片輪流對數據進行緩存。這種方式有著較明顯的缺點,首先是控制復雜,要有專門的邏輯來維護這種輪流機制 ; 其次,數據流的流向要不斷變化,限制了數據流的速率,還容易產生干擾。從數據傳輸上說,緩存芯片容量越大,對后續時序要求就越低,可減少總線操作的頻次;但從數據存儲上說,就意味著需要開辟更大的內存空間來進行進行緩沖,會增加計算機的內存開銷,而且容量越大,成本也越高。因此,在綜合考慮系統性能和成本的基礎上,選擇滿足系統需要的芯片即可。
FIFO 是 First In/First - Out 的縮寫,是先入先出的意思。 FIFO 存儲器分為寫入專用區和讀取專用區。讀操作與寫操作可以異步進行,寫入區上寫入的數據按照寫入的順序從讀取端的區中讀出,類似于吸收寫入端與讀出端速度差的一種緩沖器。計算機的串口,一般也都具有 FIFO 緩沖器(不是單一的 FIFO 存儲器,而是嵌入在設備內部)。
FIFO 存儲器的連接模式如圖所示。在 FIFO 存儲器而不是地址總線上附加了表示內部緩沖器狀態( Buffer Full ,緩沖器已滿; Buffer Empty ,緩沖器為空)的狀態引腳,連接于 FIFO 的雙方利用該狀態進行操作的控制。另外,還設計了在接通電源及復位( Reset )或由于操作中的某些異常等原因而重新初始化(無數據狀態) FIFO 的復位引腳,這可以說是 FIFO 存儲器的特點。
深 入了解 FIFO
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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