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