First Input First Output的縮寫,先入先出隊列,這是一種傳統的按序執行方法,先進入的指令先完成并引退,跟著才執行第二條指令。是一種先進先出的數據緩存器,他與普通存儲器的區別是沒有外部讀寫地址線,這樣使用起來非常簡單,但缺點就是只能順序寫入數據,順序的讀出數據,其數據地址由內部讀寫指針自動加1完成,不能像普通存儲器那樣可以由地址線決定讀取或寫入某個指定的地址。
FIFO是隊列機制中最簡單的,每個接口上只有一個FIFO隊列,表面上看FIFO隊列并沒有提供什么QoS保證,甚至很多人認為FIFO嚴格意義上不算做一種隊列技術,實則不然,FIFO是其它隊列的基礎,FIFO也會影響到衡量QoS的關鍵指標:
報文的丟棄、延時、抖動。既然只有一個隊列,自然不需要考慮如何對報文進行復雜的流量分類,也不用考慮下一個報文怎么拿、拿多少的問題,即FIFO無需流分類、調度機制,而且因為按順序取報文,FIFO無需對報文重新排序。簡化了這些實現其實也就提高了對報文時延的保證。
FIFO關心的就是隊列長度問題,隊列長度會影響到時延、抖動、丟包率。因為隊列長度是有限的,有可能被填滿,這就涉及到該機制的丟棄原則,FIFO使用Tail Drop機制。如果定義了較長的隊列長度,那么隊列不容易填滿,被丟棄的報文也就少了,但是隊列長度太長了會出現時延的問題,一般情況下時延的增加會導致抖動也增加;如果定義了較短的隊列,時延的問題可以得到解決,但是發生Tail Drop的報文就變多了。類似的問題其它排隊方法也存在。
Tail Drop機制簡單的說就是如果該隊列如果已經滿了,那么后續進入的報文被丟棄,而沒有什么機制來保證后續的報文可以擠掉已經在隊列內的報文。
FIFO隊列原理簡述
FIFO隊列不對報文進行分類,當報文進入接口的速度大于接口能發送的速度時,FIFO按報文到達接口的先后順序讓報文進入隊列,同時,FIFO在隊列的出口讓報文按進隊的順序出隊,先進的報文將先出隊,后進的報文將后出隊。
FIFO隊列具有處理簡單,開銷小的優點。但FIFO不區分報文類型,采用盡力而為的轉發模式,使對時間敏感的實時應用(如VoIP)的延遲得不到保證,關鍵業務的帶寬也不能得到保證。
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的寬度:
也就是英文資料里常看到的THE WIDTH,它指的是FIFO一次讀寫操作的數據位,就像MCU有8位和16位,ARM32位等等,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幾乎很少用到,這里只描述異步FIFO的空/滿標志產生問題。
在用到觸發器的設計中,不可避免的會遇到亞穩態的問題(關于亞穩態可查看FPGA中的亞穩態)。在涉及到觸發器的電路中,亞穩態無法徹底消除,只能想辦法將其發生的概率將到最低。
其中的一個方法就是使用格雷碼。格雷碼在相鄰的兩個碼元之間只由一位變換(二進制碼在很多情況下是很多碼元在同時變化)。這就會避免計數器與時鐘同步的時候發生亞穩態現象。但是格雷碼有個缺點就是只能定義2^n的深度,而不能像二進制碼那樣隨意的定義FIFO的深度,因為格雷碼必須循環一個2^n,否則就不能保證兩個相鄰碼元之間相差一位的條件,因此也就不是真正的格雷碼了。
第二就是使用冗余的觸發器,假設一個觸發器發生亞穩態的概率為P,那么兩個級聯的觸發器發生亞穩態的概率就為P的平方。但這會導致延時的增加。亞穩態的發生會使得FIFO出現錯誤,讀/寫時鐘采樣的地址指針會與真實的值之間不同,這就導致寫入或讀出的地址錯誤。
由于考慮延時的作用,空/滿標志的產生并不一定出現在FIFO真的空/滿時才出現。可能FIFO還未空/滿時就出現了空/滿標志。這并沒有什么不好,只要保證FIFO不出現overflow or underflow 就OK了。
以上,我們已經清楚地看到,FIFO設計最關鍵的就是產生空/滿標志的算法的不同產生了不同的FIFO。但無論是精確的空滿還是保守的空滿都是為了保證FIFO工作的可靠。
編輯:jq
-
單片機
+關注
關注
6039文章
44583瀏覽量
636504 -
存儲器
+關注
關注
38文章
7514瀏覽量
164004 -
數據傳輸
+關注
關注
9文章
1923瀏覽量
64685 -
fifo
+關注
關注
3文章
389瀏覽量
43745 -
觸發器
+關注
關注
14文章
2000瀏覽量
61224
原文標題:FIFO解析攻略
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論