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