深入學(xué)習(xí)FIFO
1、定義
? ? ? ? FIFO即First In First Out,是一種先進(jìn)先出數(shù)據(jù)存儲(chǔ)、緩沖器,我們知道一般的存儲(chǔ)器是用外部的讀寫地址來進(jìn)行讀寫,而FIFO這種存儲(chǔ)器的結(jié)構(gòu)并不需要外部的讀寫地址而是通過自動(dòng)的加一操作來控制讀寫,這也就決定了FIFO只能順序的讀寫數(shù)據(jù)。
2、FIFO分類
? ? ? ? FIFO根據(jù)讀寫時(shí)鐘是否相同分為 SCFIFO(同步FIFO)和 DCFIFO(異步FIFO)
? ? ? ? 同步FIFO,讀和寫應(yīng)用同一個(gè)時(shí)鐘。它的作用一般是做交互數(shù)據(jù)的一個(gè)緩沖,也就是說它的主要作用就是一個(gè)buffer。
? ? ? ? 異步FIFO,讀寫應(yīng)用不同的時(shí)鐘,它有兩個(gè)主要的作用,一個(gè)是實(shí)現(xiàn)數(shù)據(jù)在不同時(shí)鐘域進(jìn)行傳遞,另一個(gè)作用就是實(shí)現(xiàn)不同數(shù)據(jù)寬度的數(shù)據(jù)接口。
3、FIFO使用情況
? ? ? ?FIFO一般用于不同時(shí)鐘域之間的數(shù)據(jù)傳輸,比如FIFO的一端時(shí)AD數(shù)據(jù)采集,另一端時(shí)計(jì)算機(jī)的PCI總線,假設(shè)其AD采集的速率為16位 100K SPS,那么每秒的數(shù)據(jù)量為100K×16bit=1.6Mbps, 而PCI總線的速度為33MHz,總線寬度32bit,其最大傳輸速率為1056Mbps,在兩個(gè)不同的時(shí)鐘域間就可以采用FIFO來作為數(shù)據(jù)緩沖。另外對(duì)于不同寬度的數(shù)據(jù)接口也可以用FIFO,例如單片機(jī)位8位數(shù)據(jù)輸出,而DSP可能是16位數(shù)據(jù)輸入,在單片機(jī)與DSP連接時(shí)就可以使用FIFO來達(dá)到數(shù)據(jù)匹配的目的。
FIFO存儲(chǔ)器是系統(tǒng)的緩沖環(huán)節(jié),如果沒有FIFO存儲(chǔ)器,整個(gè)系統(tǒng)就不可能正常工作,它主要有幾方面的功能:
? ? ? ? 1) 對(duì)連續(xù)的數(shù)據(jù)流進(jìn)行緩存,防止在進(jìn)機(jī)和存儲(chǔ)操作時(shí)丟失數(shù)據(jù);
? ? ? ? 2) 數(shù)據(jù)集中起來進(jìn)行進(jìn)機(jī)和存儲(chǔ),可避免頻繁的總線操作,減輕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í)完成數(shù)據(jù)的存儲(chǔ)工作。
4、FIFO的主要參數(shù)
同步FIFO和異步FIFO略有不同,下面的參數(shù)適用于兩者。
寬度,用參數(shù)FIFO_data_size表示,它指的是 FIFO 一次讀寫操作的數(shù)據(jù)位,也就是FIFO存儲(chǔ)的數(shù)據(jù)寬度;
深度,用參數(shù)FIFO_addr_size表示,也就是地址的大小,也就是說能存儲(chǔ)多少個(gè)數(shù)據(jù);
滿標(biāo)志,full,當(dāng)FIFO中的數(shù)據(jù)滿了以后將不再能進(jìn)行數(shù)據(jù)的寫入,以阻止FIFO的寫操作繼續(xù)向FIFO中寫數(shù)據(jù)而造成溢出(overflow);
空標(biāo)志,empty,當(dāng)FIFO為空的時(shí)候?qū)⒉荒苓M(jìn)行數(shù)據(jù)的讀出,以阻止FIFO的讀操作繼續(xù)從FIFO中讀出數(shù)據(jù)而造成無效數(shù)據(jù)的讀出(underflow);
寫地址,w_addr,由自動(dòng)加一生成,將數(shù)據(jù)寫入該地址;
讀地址,r_addr,由自動(dòng)加一生成,將該地址上的數(shù)據(jù)讀出;
同步FIFO和異步FIFO的最主要的不同就體現(xiàn)在空滿標(biāo)志產(chǎn)生的方式上,由此引出兩者一些不同的參數(shù)。
同步FIFO
時(shí)鐘,clk,rst,讀寫應(yīng)用同一個(gè)時(shí)鐘;
計(jì)數(shù)器,count,用計(jì)數(shù)器來進(jìn)行空滿標(biāo)志的判斷;
異步FIFO
時(shí)鐘,clk_w,rst_w,clk_r,rst_r,讀寫應(yīng)用不同的時(shí)鐘;
指針,w_pointer_gray,r_pointer_gray,用指針來判斷空滿標(biāo)識(shí);
同步指針,w_pointer_gray_sync,r_pointer_gray_sync,指針的同步操作,用來做對(duì)比產(chǎn)生空滿標(biāo)志符;
5、FIFO設(shè)計(jì)的難點(diǎn)
? ? ? ? FIFO設(shè)計(jì)的難點(diǎn)在于怎樣判斷FIFO的空/滿狀態(tài)。為了保證數(shù)據(jù)正確的寫入或讀出,而不發(fā)生溢出或讀空的狀態(tài)出現(xiàn),必須保證FIFO在滿的情況下,不能進(jìn)行寫操作。在空的狀態(tài)下不能進(jìn)行讀操作。怎樣判斷FIFO的滿/空就成了FIFO設(shè)計(jì)的核心問題。由于同步FIFO幾乎很少用到,這里只描述異步FIFO的空/滿標(biāo)志產(chǎn)生問題。
5.1、亞穩(wěn)態(tài)
? ? ? ? 在用到觸發(fā)器的設(shè)計(jì)中,不可避免的會(huì)遇到亞穩(wěn)態(tài)的問題。亞穩(wěn)態(tài)主要發(fā)生在異步信號(hào)檢測(cè)、跨時(shí)鐘域信號(hào)傳輸以及復(fù)位電路等常用設(shè)計(jì)中。在涉及到觸發(fā)器的電路中,亞穩(wěn)態(tài)無法徹底消除,只能想辦法將其發(fā)生的概率將到最低。
? ? ? ? 亞穩(wěn)態(tài)發(fā)生的原因:
? ? ? ? (1)在跨時(shí)鐘域信號(hào)傳輸時(shí),由于源寄存器時(shí)鐘和目的寄存器時(shí)鐘相移未知,所以源寄存器數(shù)據(jù)發(fā)出數(shù)據(jù),數(shù)據(jù)可能在任何時(shí)間到達(dá)異步時(shí)鐘域的目的寄存器,所以無法保證滿足目的寄存器Tsu和Th的要求;
? ? ? ? (2)在異步信號(hào)采集中,由于異步信號(hào)可以在任意時(shí)間點(diǎn)到達(dá)目的寄存器,所以也無法保證滿足目的寄存器Tsu和Th的要求;
? ? ? ? (3)在異步復(fù)位電路中,如果復(fù)位信號(hào)的釋放時(shí)間剛好是發(fā)生在時(shí)鐘的有效邊沿,難以保證滿足恢復(fù)時(shí)間(Recovery Time)以及去除時(shí)間(Removal Time),從而出現(xiàn)亞穩(wěn)態(tài)。
? ? ? ? 當(dāng)數(shù)據(jù)在目的寄存器Tsu-Th時(shí)間窗口發(fā)生變化,也即當(dāng)數(shù)據(jù)的建立時(shí)間或者保持時(shí)間不滿足時(shí),就可能發(fā)生亞穩(wěn)態(tài)現(xiàn)象。

由圖可知,當(dāng)產(chǎn)生亞穩(wěn)態(tài)后Tco時(shí)間后會(huì)有Tmet(決斷時(shí)間)的振蕩時(shí)間段,當(dāng)振蕩結(jié)束回到穩(wěn)定狀態(tài)時(shí)為“0”或者“1”,這個(gè)是隨機(jī)的。因此,會(huì)對(duì)后續(xù)電路判斷造成影響。
? ? ? ? 亞穩(wěn)態(tài)產(chǎn)生的后果
? ? ? ? 1、亞穩(wěn)態(tài)中間態(tài)時(shí)間變長(zhǎng):亞穩(wěn)態(tài)是觸發(fā)器的一個(gè)固有特性,正常采樣也會(huì)有一個(gè)亞穩(wěn)態(tài)時(shí)間。如果觸發(fā)器觸發(fā)器的輸入電壓采樣時(shí)間過短,則觸發(fā)器需要花很長(zhǎng)時(shí)間來實(shí)現(xiàn)輸出邏輯達(dá)到標(biāo)準(zhǔn)電平,在這段時(shí)間里輸出端在高低電平之間處于振蕩狀態(tài),而不是等于理想輸出值。當(dāng)建立時(shí)間和保持時(shí)間滿足時(shí),觸發(fā)器也會(huì)經(jīng)歷采樣—亞穩(wěn)態(tài)—隨后穩(wěn)定輸出。而出現(xiàn)亞穩(wěn)態(tài)問題時(shí),亞穩(wěn)態(tài)(中間態(tài))時(shí)間變長(zhǎng)。
? ? ? ? 2、亞穩(wěn)態(tài)的輸出不一定正確:正常工作時(shí),觸發(fā)器經(jīng)歷較短的亞穩(wěn)態(tài)時(shí)間,隨后會(huì)正確輸出;而出現(xiàn)亞穩(wěn)態(tài)問題時(shí),觸發(fā)器經(jīng)歷較長(zhǎng)的亞穩(wěn)態(tài)時(shí)間,最終輸出穩(wěn)定但無法保證正確(是穩(wěn)定的標(biāo)準(zhǔn)電平信號(hào),但難以保證是輸入對(duì)應(yīng)輸出);
? ? ? ? 常用對(duì)亞穩(wěn)態(tài)消除有三種方式:
對(duì)跨時(shí)鐘域的信號(hào)做跨時(shí)鐘域傳輸處理
采用異步FIFO或者握手協(xié)議對(duì)跨時(shí)鐘域數(shù)據(jù)通信進(jìn)行緩沖設(shè)計(jì)
對(duì)異步復(fù)位電路采用異步復(fù)位、同步釋放處理
對(duì)異步信號(hào)進(jìn)行同步處理
5.2、FIFO設(shè)計(jì)的方法
(1)使用格雷碼
? ? ? ? 格雷碼在相鄰的兩個(gè)碼元之間只由一位變換(二進(jìn)制碼在很多情況下是很多碼元在同時(shí)變化)。這就會(huì)避免計(jì)數(shù)器與時(shí)鐘同步的時(shí)候發(fā)生亞穩(wěn)態(tài)現(xiàn)象。但是格雷碼有個(gè)缺點(diǎn)就是只能定義2n的深度,而不能像二進(jìn)制碼那樣隨意的定義FIFO的深度,因?yàn)楦窭状a必須循環(huán)一個(gè)2n,否則就不能保證兩個(gè)相鄰碼元之間相差一位的條件,因此也就不是真正的各雷碼了。
? ? ? ? 格雷碼實(shí)現(xiàn)多比特跨時(shí)鐘域轉(zhuǎn)換的原理:因?yàn)閒ifo中地址是逐次+1的,而格雷碼相鄰兩位數(shù)據(jù)一次只有一位數(shù)據(jù)發(fā)生變化。因此,將寫地址(讀地址)變換成格雷碼,雖然地址是多比特的,但是每次變化只有1bit發(fā)生變化。這就是將二進(jìn)制的地址轉(zhuǎn)換成格雷碼的好處了。
如果是將寫地址變成格雷碼,轉(zhuǎn)換完以后再進(jìn)行垮時(shí)鐘域到讀時(shí)鐘域去就能最大限度的降低垮時(shí)鐘域帶來的風(fēng)險(xiǎn)(亞穩(wěn)態(tài))。(敲黑板:先轉(zhuǎn)換成格雷碼再跨時(shí)鐘域)
二進(jìn)制到格雷碼:
? ? ? ? 二進(jìn)制右移一位后與原來的二進(jìn)制按位異或 = 格雷碼
格雷碼轉(zhuǎn)二進(jìn)制:
? ? ? ? 格雷碼的最高位作為二進(jìn)制的最高位,然后將二進(jìn)制的最高位和格雷碼的次高位異或作為二進(jìn)制的次高位,依次類推。
(2)使用冗余的觸發(fā)器
? ? ? ? 假設(shè)一個(gè)觸發(fā)器發(fā)生亞穩(wěn)態(tài)的概率為P,那么兩個(gè)及聯(lián)的觸發(fā)器發(fā)生亞穩(wěn)態(tài)的概率就為P的平方。但這回導(dǎo)致延時(shí)的增加。亞穩(wěn)態(tài)的發(fā)生會(huì)使得FIFO出現(xiàn)錯(cuò)誤,讀/寫時(shí)鐘采樣的地址指針會(huì)與真實(shí)的值之間不同,這就導(dǎo)致寫入或讀出的地址錯(cuò)誤。由于考慮延時(shí)的作用,空/滿標(biāo)志的產(chǎn)生并不一定出現(xiàn)在FIFO真的空/滿時(shí)才出現(xiàn)??赡蹻IFO還未空/滿時(shí)就出現(xiàn)了空/滿標(biāo)志。這并沒有什么不好,只要保證FIFO不出現(xiàn)overflow or underflow 就OK了。
(3)空滿狀態(tài)的判斷
? ? ? ? 要判斷fifo的狀態(tài),就需要知道讀寫地址。通過判斷讀寫地址的差值來判斷狀態(tài)。其中存在一直特殊情況:讀寫地址指針指向同一個(gè)地址,但是可能是滿,也可能是空。
? ? ? ? 具體分析:因?yàn)閒ifo是回卷式的寫和讀,這也就是說如果fifo深度為1023,如果寫地址在1023,寫地址指針會(huì)重新回到0地址,如果此時(shí)讀地址還在地址0,就會(huì)存在讀寫地址都在地址0。而空的時(shí)候,讀寫地址也存在都在0地址的問題。
? ? ? ? 方法:將讀寫地址擴(kuò)展一位,當(dāng)讀寫地址的值相等時(shí),為空;讀寫地址除最高位不同,其余相同為滿。
6、FIFO深度(存儲(chǔ)容量)計(jì)算
? ? ? ? 異步FIFO,讀寫時(shí)鐘不同頻,那么FIFO主要用于數(shù)據(jù)緩存,我們選擇的FIFO深度應(yīng)該能夠保證在最極端的情況下,仍然不會(huì)溢出。因此考慮的前提一般都是寫時(shí)鐘頻率大于讀時(shí)鐘頻率,但是若寫操作是連續(xù)的數(shù)據(jù)流,那么再大的FIFO都無法保證數(shù)據(jù)不溢出。因此可以認(rèn)為這種情況下寫數(shù)據(jù)的傳輸是“突發(fā)Burst”的,即寫操作并不連續(xù),設(shè)計(jì)者需要根據(jù)滿標(biāo)志控制或者自己來控制寫操作的起止。
? ? ? ? 宏觀地,從整個(gè)時(shí)間域上看,"寫數(shù)據(jù)=讀數(shù)據(jù)",這個(gè)條件必須要滿足,如果這個(gè)大條件不滿足的話,用FIFO是沒有效果的。但是在發(fā)送方"突發(fā)"發(fā)送數(shù)據(jù)的時(shí)間T內(nèi),是很有可能寫數(shù)據(jù)>讀數(shù)據(jù)的,因此FIFO的深度要能夠保證,在這段時(shí)間T內(nèi),如果接收方未能將發(fā)送方發(fā)送的數(shù)據(jù)接收完畢的話,剩下的數(shù)據(jù)都是可以存儲(chǔ)在FIFO內(nèi)部而且不會(huì)溢出的,那么在發(fā)送方停止發(fā)送數(shù)據(jù)的"空閑時(shí)隙"內(nèi),接收方可以從容地接收剩下來的數(shù)據(jù)。
如果數(shù)據(jù)流連續(xù)不斷則FIFO深度無論多少,只要讀寫時(shí)鐘不同源同頻則都會(huì)丟數(shù);
FIFO用于緩沖塊數(shù)據(jù)流,一般用在寫快讀慢時(shí),
FIFO深度 / (寫入速率 - 讀出速率) =? FIFO被填滿時(shí)間? ?應(yīng)大于 數(shù)據(jù)包傳送時(shí)間 = 數(shù)據(jù)量 / 寫入速率。
? ? ? ? FIFO深度計(jì)算的關(guān)鍵在于:在規(guī)定時(shí)間內(nèi)傳輸?shù)臄?shù)據(jù)等于接收的數(shù)據(jù),寫快讀慢的情況下,突發(fā)burst寫入的數(shù)據(jù)減去該burst時(shí)間內(nèi)讀出的數(shù)據(jù),多余的數(shù)據(jù)需要能緩沖下來,讓接收端在剩下空閑的時(shí)間能從容地把多余的數(shù)據(jù)讀出來。
例題
1.讀寫沒有空閑周期。(fA>fB)
fA = 80MHz;fB = 50MHz;Burst Length = 120
讀寫之間沒有空閑周期,這意味著突發(fā)中的所有項(xiàng)目都將在連續(xù)的時(shí)鐘周期內(nèi)寫入和讀取。
計(jì)算方法:
總數(shù)據(jù)傳輸:120
寫一個(gè)數(shù)據(jù)需要的時(shí)間 = 1 / 80MHz = 12.5ns
寫入所有數(shù)據(jù)需要的時(shí)間 = 120 * 12.5ns = 1500ns
讀一個(gè)數(shù)據(jù)需要的時(shí)間 = 1 / 50MHz = 20ns
每1500ns,120個(gè)數(shù)據(jù)被寫入FIFO,但讀一個(gè)數(shù)據(jù)需要20ns的時(shí)間
則1500ns內(nèi)讀出多少個(gè)數(shù)據(jù),1500 / 20 = 75
剩下的沒有讀出,就存在FIFO中,則多余的數(shù)據(jù)為120 - 75 = 45
快捷方法:FIFO的最小深度 =120 - 120*50/80 = 45
補(bǔ)充:讀寫沒有空閑,若fA<=fB,則FIFO不會(huì)寫滿,深度為1即可。
2.讀寫都有空閑周期。(讀寫速率大小隨意,可以相等)
fA = 80MHz;fB = 50MHz;Burst Length = 120
兩個(gè)連續(xù)寫入之間的空閑周期為 = 1(寫使能占得百分比為50%)
兩個(gè)連續(xù)讀取之間的空閑周期為 = 3(讀使能占得百分比為25%)
計(jì)算方法:
每寫入一個(gè)數(shù)據(jù)等待1個(gè)周期再寫入下個(gè)數(shù)據(jù),即2周期寫入1個(gè)數(shù)據(jù)。
每讀出一個(gè)數(shù)據(jù)等待3個(gè)周期再讀出下個(gè)數(shù)據(jù),即4周期讀出1個(gè)數(shù)據(jù)。
寫一個(gè)數(shù)據(jù)需要的時(shí)間 = 2 * (1 / 80MHz) = 25ns
寫一個(gè)突發(fā)需要的時(shí)間 = 120 * 25ns = 3000ns
讀一個(gè)數(shù)據(jù)需要的時(shí)間 = 4 * (1 / 50MHz) = 80ns
每3000ns,120個(gè)數(shù)據(jù)被寫入FIFO,但讀一個(gè)數(shù)據(jù)需要80ns的時(shí)間
則3000ns內(nèi)讀出多少個(gè)數(shù)據(jù),3000 / 80 = 37.5,F(xiàn)IFO深度=120-37.5=83。
快捷方法:FIFO深度 = 120 - 120*(50/4)/(80/2)=82.5=83。
3.考慮背靠背,讀寫速率相等。
讀寫速率相等;每100個(gè)時(shí)鐘寫入80個(gè)數(shù)據(jù);每10個(gè)時(shí)鐘讀取8個(gè)數(shù)據(jù);突發(fā)長(zhǎng)度為160 (這個(gè)條件其實(shí)多余)
計(jì)算方法:
每100個(gè)時(shí)鐘寫入80個(gè)數(shù)據(jù),那剩下20個(gè)時(shí)鐘周期去哪了?
每10個(gè)時(shí)鐘讀取8個(gè)數(shù)據(jù),那剩下2個(gè)時(shí)鐘周期去哪了?
剩下的周期在哪我們不管,只考慮最差的情況,即前20個(gè)時(shí)鐘周期空閑,后80個(gè)周期寫完80個(gè)數(shù)據(jù),立馬又是寫請(qǐng)求,這次是前80個(gè)時(shí)鐘周期寫完80個(gè)數(shù)據(jù),后20個(gè)時(shí)鐘周期空閑。即連續(xù)的寫入,又稱為背靠背。也就可以看成一個(gè)突發(fā)寫入是80+80=160。
寫一個(gè)突發(fā)需要的時(shí)間:160時(shí)鐘周期
則160個(gè)時(shí)鐘周期內(nèi)讀出多少個(gè)數(shù)據(jù),160*8/10=128。
FIFO深度 = 160 - 128 = 32。
4.考慮背靠背,讀寫速率不等。
fA = 20MHz;fB = 40MHz;每1000個(gè)時(shí)鐘周期寫入500個(gè)數(shù)據(jù);每4個(gè)時(shí)鐘周期讀出1個(gè)數(shù)據(jù)
計(jì)算方法:
考慮到“背靠背”的情況突發(fā)長(zhǎng)度則為500 * 2 = 1000
則為每1000個(gè)時(shí)鐘周期寫入1000個(gè)數(shù)據(jù)
每4個(gè)周期,讀取一個(gè)數(shù)據(jù)。
寫一個(gè)數(shù)據(jù)需要的時(shí)間 = 1 / 20MHz = 50ns
寫一個(gè)突發(fā)需要的時(shí)間 = 1000 * 50ns = 50000ns
讀一個(gè)數(shù)據(jù)需要的時(shí)間 = 4 * (1 / 40MHz) = 100ns
每50000ns,120個(gè)數(shù)據(jù)被寫入FIFO,但讀一個(gè)數(shù)據(jù)需要100ns的時(shí)間
可以計(jì)算出,50000ns內(nèi)讀出多少個(gè)數(shù)據(jù),50000 /100 = 500
剩下的沒有讀出,就存在FIFO中,則需要1000- 500 = 500
明德?lián)P除了培訓(xùn)學(xué)習(xí)還有項(xiàng)目承接業(yè)務(wù),擅長(zhǎng)的項(xiàng)目主要包括的方向有以下幾個(gè)方面:
1. MIPI視頻拼接
2. SLVS-EC轉(zhuǎn)MIPI接口(IMX472 IMX492)
3. PCIE采集系統(tǒng)
4. 圖像項(xiàng)目
5. 高速多通道ADDA系統(tǒng)
6. 基于FPGA板卡研發(fā)
7. 多通道高靈敏電荷放大器
8. 射頻前端
需要了解相關(guān)信息可以聯(lián)系:小甜老師 13112028098(微信同號(hào))
深入學(xué)習(xí)FIFO的評(píng)論 (共 條)
