FIFO作為FPGA崗位求職過(guò)程中最常被問(wèn)到的基礎(chǔ)知識(shí)點(diǎn),也是項(xiàng)目中最常被使用到的IP,其意義是非常重要的。本文基于對(duì)FIFO Generator的Xilinx官方手冊(cè)的閱讀與總結(jié),匯總主要知識(shí)點(diǎn)如下:
類型
FIFO的類型區(qū)分主要根據(jù)FIFO在實(shí)現(xiàn)時(shí)利用的是芯片中的哪些資源,其分類主要有以下四種:
shift register FIFO:通過(guò)寄存器來(lái)實(shí)現(xiàn)的,這種類型的FIFO最好少用,因?yàn)槲覀兌贾繤F資源在FPGA是非常珍貴的。
built-in FIFO:這種類型的FIFO只有7系列之后(包括UltraScale)才有。筆者的理解是一種集成的FIFO硬核
Block Ram FIFO:通過(guò)塊RAM的資源配置形成的FIFO,其本質(zhì)是Block RAM+一些外設(shè)電路。
Distributed Ram FIFO:通過(guò)分布式RAM配置形成的FIFO,與BRAM類似,只是RAM的類型不一樣。
Reset
shift register FIFO和built-in FIFO的復(fù)位信號(hào)是不可選的,即一定存在的。對(duì)于shift register FIFO和7系列的built-in FIFO,Xilinx只提供了異步復(fù)位;而對(duì)于UltraScale,復(fù)位是同步復(fù)位信號(hào),但提供了w_rst_busy和rd_rst_busy輸出信號(hào)表示FIFO是否已經(jīng)復(fù)位完畢。
Block RAM FIFO 和 Distributed RAM FIFO的復(fù)位信號(hào)是可選的。對(duì)于共用時(shí)鐘的FIFO,選擇同步復(fù)位和異步復(fù)位的區(qū)別主要在于是否復(fù)位信號(hào)是否和共用時(shí)鐘同步;當(dāng)選擇異步復(fù)位時(shí),可以Enable Safety Circuit,顧名思義就是讓電路更安全,即通過(guò)復(fù)位完成信號(hào)wr_rst_busy和rd_rst_busy來(lái)表示是否FIFO已經(jīng)復(fù)位完成。對(duì)于獨(dú)立時(shí)鐘的FIFO,即讀和寫的時(shí)鐘分開,Enable Reset Synchronication時(shí)只有一個(gè)rst(實(shí)際上這個(gè)復(fù)位是異步復(fù)位),不使能時(shí)有兩個(gè)時(shí)鐘域的rst,分別為wr_rst和rd_rst,而這兩個(gè)復(fù)位信號(hào)實(shí)際上是同步于各自的時(shí)鐘的,同時(shí)也能Enable Safety Circuit,是不是覺(jué)得好像整錯(cuò)了,其實(shí)Xilinx的官方文檔就是這么說(shuō)明的,如果還是覺(jué)得有問(wèn)題,實(shí)踐一下……
其實(shí)上邊的如果不理解,我自己總結(jié)了一下:看復(fù)位是同步復(fù)位還是異步復(fù)位,只需要看信號(hào)的名字,對(duì)于srst(Synchronized Reset)和wr_rst/rd_rst,這幾個(gè)rst是同步復(fù)位,一個(gè)同步于共用時(shí)鐘,其余兩個(gè)同步于各自的時(shí)鐘域;對(duì)于rst,則認(rèn)為是異步復(fù)位。
寫操作
寫數(shù)據(jù)只有在din輸入同時(shí)wr_ack被斷言時(shí)才寫入到FIFO中。這里wr_ack是對(duì)數(shù)據(jù)接收的應(yīng)答,斷言時(shí)表示接收成功。當(dāng)然也可以不使能wr_ack,這樣子其實(shí)也沒(méi)什么大問(wèn)題,只是wr_ack的存在會(huì)讓數(shù)據(jù)的寫入更加安全。
需要注意的一個(gè)關(guān)鍵點(diǎn)是,F(xiàn)IFO被寫滿時(shí),即使再輸入數(shù)據(jù),寫入請(qǐng)求還是會(huì)被忽略的,F(xiàn)IFO中的數(shù)據(jù)保持不變。
滿標(biāo)志
滿標(biāo)志有full和almost_full兩種。full表示不能寫數(shù)據(jù)了,almost_full則表示只能再寫入一個(gè)數(shù)據(jù)。當(dāng)full被斷言時(shí),寫請(qǐng)求會(huì)被忽略掉,同時(shí)overflow溢出標(biāo)志被斷言。
【注】built-in FIFO不支持almost_full標(biāo)志。
寫操作時(shí)序分析
上圖是從datasheet中copy的一個(gè)典型的寫操作時(shí)序圖。
當(dāng)wr_en被使能為1時(shí),表示寫操作開始,并在時(shí)鐘上升沿開始寫入。此時(shí)full為低電平表示FIFO未滿,可以寫入。
當(dāng)數(shù)據(jù)寫入成功時(shí),wr_ack被斷言,即拉高表示數(shù)據(jù)寫入成功***(此時(shí)我們還是得注意寫入成功那個(gè)時(shí)刻,wr_ack實(shí)際上還是低電平,真正能檢測(cè)到高電平的還是得在下個(gè)時(shí)鐘沿)***。
當(dāng)FIFO只能再支持寫一個(gè)數(shù)據(jù)時(shí),almost_full被斷言***(應(yīng)該注意到,這些標(biāo)志信號(hào)都是有一個(gè)cycle的延遲的,即實(shí)際上當(dāng)我們檢測(cè)到amost_full拉高時(shí),最后一個(gè)數(shù)據(jù)也在同時(shí)刻寫入FIFO,所以FIFO在這個(gè)時(shí)刻已經(jīng)滿了)***。
當(dāng)FIFO的almost_full拉高時(shí),再次寫入一個(gè)數(shù)據(jù),則full也被斷言。
當(dāng)FIFO的full被斷言時(shí),再寫入數(shù)據(jù),wr_ack被拉低,同時(shí)overflow溢出信號(hào)被斷言。
在FIFO被寫滿時(shí),如果開始讀操作,full信號(hào)會(huì)被拉低,此時(shí)數(shù)據(jù)又可以再次寫入FIFO。
讀操作
當(dāng)read使能且FIFO不是空的時(shí)候,數(shù)據(jù)開始從FIFO讀出。同時(shí)valid信號(hào)被斷言表示數(shù)據(jù)有效。讀操作只有在FIFO有數(shù)據(jù)時(shí)才能成功,當(dāng)FIFO是空的時(shí),此時(shí)讀信號(hào)會(huì)被忽略,同時(shí)underflow會(huì)被斷言表示下溢,數(shù)據(jù)輸出不會(huì)發(fā)生任何變化。
空信號(hào)
almost_empty表示FIFO即將被讀空,只剩下一個(gè)數(shù)據(jù)。empty表示FIFO已經(jīng)被讀空,只有當(dāng)FIFO再次被寫入數(shù)據(jù)時(shí),empty才會(huì)再次被拉低。almost_empty和empty都同步于rd_clk時(shí)鐘域。當(dāng)FIFO被讀空時(shí),再進(jìn)行讀寫則underflow信號(hào)會(huì)被斷言。
【注】built-in FIFO不支持almost_empty信號(hào)
當(dāng)讀操作和寫操作同時(shí)發(fā)生在empty被斷言時(shí),寫操作可以正常執(zhí)行,讀操作會(huì)被忽略,在下個(gè)時(shí)鐘,empty和underflow被拉低后,才能繼續(xù)進(jìn)行讀操作。
讀操作時(shí)序分析
FIFO的讀操作有兩種模式,Standard Read和First-Word Fall-Through。簡(jiǎn)單地說(shuō),標(biāo)志讀模式下,數(shù)據(jù)會(huì)在請(qǐng)求的下一個(gè)時(shí)鐘給出,而FWFT則在請(qǐng)求的同一個(gè)時(shí)鐘給出。
Standard Read
標(biāo)準(zhǔn)讀模式下,當(dāng)empty沒(méi)有被斷言時(shí),表示FIFO中有數(shù)據(jù)可讀。此時(shí)使能rd_en,在下個(gè)時(shí)鐘上升沿即開始讀取數(shù)據(jù),同時(shí)valid被拉高表示讀取數(shù)據(jù)有效。當(dāng)讀到FIFO只剩一個(gè)數(shù)據(jù)時(shí),almost_empty被斷言;當(dāng)讀完所有數(shù)據(jù)時(shí),empty被斷言。此時(shí)如果再進(jìn)行讀取,則underflow被斷言,表示下溢,同時(shí)valid拉低表示數(shù)據(jù)無(wú)效。
First-Word Fall-Through
在FWFT模式下,數(shù)據(jù)總是能被提前獲取的,可以這么理解,在我們還不需要讀取FIFO的數(shù)據(jù)的時(shí)候,其實(shí)我們不在乎FIFO中第一個(gè)數(shù)據(jù)是什么,但FWFT模式下,第一個(gè)數(shù)據(jù)提前進(jìn)入了準(zhǔn)備發(fā)送的狀態(tài),即我們可以dout處看到即將輸出的數(shù)據(jù)是什么,而當(dāng)我們開始讀的時(shí)候,下一個(gè)數(shù)據(jù)就進(jìn)入準(zhǔn)備狀態(tài),也被我們提前獲取了。
比較兩種模式下的flag信號(hào)。almost_empty是在FIFO中還剩下一個(gè)數(shù)據(jù)是被斷言,empty是在把最后一個(gè)數(shù)據(jù)讀取完了之后被斷言,在SR模式下,empty是在把最后一個(gè)數(shù)據(jù)讀出來(lái)的同時(shí)拉高,在FWFT模式下,empty是在獲取最后一個(gè)數(shù)據(jù)后才拉高,因?yàn)槲覀兪翘崆爸雷詈笠粋€(gè)數(shù)據(jù),此時(shí)的數(shù)據(jù)還是停留在FIFO中,只有把它讀出來(lái)了,F(xiàn)IFO才是空的,empty才會(huì)被斷言。inderflow都在讀空之后還試圖繼續(xù)讀取的時(shí)候才會(huì)拉高,所以u(píng)nderflow總是比empty慢一拍。valid總是和數(shù)據(jù)是同步的。
同時(shí)讀寫時(shí)序分析
下圖是標(biāo)準(zhǔn)讀寫模式下的時(shí)序圖,原理前面已經(jīng)講過(guò)了,這里提供給大家驗(yàn)證自己的理解是否正確。
握手信號(hào)
FIFO的握手信號(hào)主要有wr_ack、valid、underflow和overflow。
wr_ack:write acknowledge,即寫操作應(yīng)答。當(dāng)寫入成功時(shí),wr_ack斷言回應(yīng)表示寫入數(shù)據(jù)成功。
valid:valid信號(hào)表示數(shù)據(jù)有效的意思,它的時(shí)序在SR和FWFT模式中均表現(xiàn)為數(shù)據(jù)有效,但和rd_en的時(shí)序相位有區(qū)別。
underflow:下溢信號(hào)。當(dāng)FIFO為空且繼續(xù)讀取數(shù)據(jù)時(shí),則會(huì)出現(xiàn)下溢。
overflow:上溢信號(hào)。當(dāng)FIFO寫滿后還繼續(xù)寫入數(shù)據(jù)時(shí),則出現(xiàn)上溢。
Programmable Flags
用戶自定義閾值標(biāo)志位。分為Programmable full和Programmable empty兩種。前者表示FIFO寫滿狀態(tài)的閾值,后者表示FIFO讀空狀態(tài)的閾值。簡(jiǎn)單地說(shuō),就是不管FIFO的深度,你想讓它存入多少數(shù)據(jù)時(shí)就認(rèn)為已經(jīng)裝滿了,或者你讓他認(rèn)為還剩多少數(shù)據(jù)就已經(jīng)算讀空,可以自行設(shè)置。
對(duì)于prog_full和prog_empty,可以設(shè)置為單閾值(single)和多閾值(multiple),設(shè)置單閾值時(shí),大于或等于(小于或等于)閾值就會(huì)斷言滿(空)信號(hào)。而設(shè)置多閾值,就可以出現(xiàn)滯留效果,以prog_full為例,當(dāng)設(shè)置assert threshold為100,negate threshold為80時(shí),當(dāng)FIFO中數(shù)據(jù)沒(méi)到100時(shí),只有大于100后才會(huì)斷言滿,而此時(shí)斷言滿之后被讀到100以下后,F(xiàn)IFO仍然認(rèn)為是滿的,只有持續(xù)讀到小于80,才會(huì)認(rèn)為未滿,即negate。
其次,對(duì)于閾值的設(shè)定,既可以設(shè)置為常數(shù),也可以設(shè)置為一個(gè)自定義輸入。當(dāng)定義為自定義輸入的時(shí)候,F(xiàn)IFO的滿空狀態(tài)就變成自適應(yīng)的了,隨時(shí)可以通過(guò)閾值輸入進(jìn)行修改。
Data Counts
Data Count只能用于共用時(shí)鐘。對(duì)于讀寫時(shí)鐘分開的情況,則分別用Read Data Count和Write Data Count來(lái)表示FIFO中的數(shù)據(jù),異步FIFO中雖然是同一個(gè)FIFO,但rd_data_cnt和wr_data_cnt中的數(shù)值不一定是相等的,為什么這么設(shè)置,因?yàn)榘踩?!具體說(shuō)明:
Read Data Count 和 Write Data Count 都是采用的保守估計(jì)的方式。什么是保守估計(jì),意思就是假設(shè)FIFO中至少有8個(gè)數(shù)據(jù)可讀,但FIFO只跟你說(shuō)我這里只有8個(gè)數(shù)據(jù)可讀,那么你就會(huì)認(rèn)為只能讀8個(gè)數(shù)據(jù),實(shí)際上可能能讀9個(gè)或者10個(gè),這么做的原因時(shí)為了保證FIFO讀操作的安全性,后面我們分析異步FIFO的時(shí)候就能深刻理解這么做的精妙之處,這就是保守估計(jì)。類似的,當(dāng)FIFO中還可以寫至少8個(gè)數(shù)據(jù)時(shí),F(xiàn)IFO會(huì)說(shuō)只能寫8個(gè)數(shù)據(jù)了,這樣子你也只會(huì)寫8個(gè)數(shù)據(jù),實(shí)際上FIFO可以寫9-10個(gè)左右。datasheet中的原文表述為Read data count (rd_data_count) pessimistically reports the number of words available for reading. The count is guaranteed to never over-report the number of words available in the FIFO (although it may temporarily under-report the number of words available) to ensure that the user design never underflows the FIFO.
那么,F(xiàn)IFO是怎么實(shí)現(xiàn)這種保守估計(jì)的呢?結(jié)合下圖一起分析,我們以Write Data Count為例,由于wr_data_cnt同步于wr_clk,wr_en也同步于wr_clk,所以wr_en使能后,每寫入一個(gè)data,都可以在下個(gè)時(shí)鐘沿反饋到wr_data_cnt上,寫入一個(gè)數(shù)據(jù),wr_data_cnt就加一;相應(yīng)的,讀出一個(gè)數(shù)據(jù),wr_data_cnt也需要減一,才能正確反應(yīng)FIFO中的數(shù)據(jù)量。但對(duì)于rd_en,由于rd_en是同步于rd_clk的,所以rd_en的使能需要通過(guò)一系列的時(shí)鐘同步到wr_clk中才能反映到wr_data_cnt上,通常采用的方式是格雷碼和打拍子的方式,如下圖所示,可以看到需要將Read Counter通過(guò)格雷碼轉(zhuǎn)換(格雷碼轉(zhuǎn)換可以消除很多中間不定態(tài),大大增強(qiáng)了穩(wěn)定性),再進(jìn)行跨時(shí)鐘域傳輸,這里跨時(shí)鐘域傳輸一般可以選擇打拍子的方式,由于已經(jīng)轉(zhuǎn)化成了格雷碼,此時(shí)多bit傳輸就可以變成單bit傳輸,因?yàn)橄噜弒tate只有其中一個(gè)bit發(fā)生了變化,單bit跨時(shí)鐘域傳輸就可以采用打拍子的方式進(jìn)行時(shí)鐘域轉(zhuǎn)換,這樣子就造成了的結(jié)果就是傳送到wr_clk時(shí)鐘域時(shí)的Read Counter的數(shù)值是過(guò)去的Read Counter,比最新的Read Counter要小,因此Write Counter-Read Counter偏大,從而認(rèn)為FIFO中有更多的數(shù)據(jù)存儲(chǔ)(實(shí)際上并沒(méi)有那么多數(shù)據(jù)),因此wr_data_cnt輸出的信息就是FIFO中最多有多少個(gè)數(shù)據(jù),至少還能寫入多少個(gè)數(shù)據(jù),而我們能知道的就是我們只要寫入的數(shù)據(jù)不超過(guò)它的最小值,就能保證FIFO永遠(yuǎn)不會(huì)寫滿,這樣子安全性就提高了。
Non-symmetric Aspect Ratios
非對(duì)稱比例用于設(shè)置寫數(shù)據(jù)和讀數(shù)據(jù)的位寬不同的情況。用例子說(shuō)明如下:
上圖表示1:4的Aspect Ratio,即寫一次只能寫一個(gè)數(shù)據(jù),但讀可以一次讀四個(gè)數(shù)據(jù),寫的時(shí)候是從高位寫到低位。需要注意的一個(gè)點(diǎn)是,對(duì)于讀寫非對(duì)稱的情況,如上所述,假設(shè)讀空了FIFO之后,empty被斷言,則此時(shí)寫入一個(gè)數(shù)據(jù)并不能拉低empty,必須寫入至少四個(gè)才能將empty拉低,即FIFO中遵循位寬最大法則。
-
Xilinx
+關(guān)注
關(guān)注
71文章
2159瀏覽量
120884 -
fifo
+關(guān)注
關(guān)注
3文章
387瀏覽量
43503 -
generator
+關(guān)注
關(guān)注
0文章
57瀏覽量
33058
原文標(biāo)題:Xilinx FIFO詳細(xì)解析
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論