Xilinx IP解析之FIFO Generator v13.2
一. IP概述
可參考Xilinx官網fifo_generator概述,
以下翻譯自官網此IP的概述。
產品描述:
LogiCORE?IP FIFO生成器內核生成經過充分驗證的先進先出(FIFO)內存隊列,非常適合需要按順序存儲和檢索數據的應用。
該內核為所有FIFO配置提供了優化的解決方案,并在利用最少資源的同時提供了最高性能(高達500 MHz)。通過Vivado?Design Suite提供的結構可以由用戶自定義,包括寬度,深度,狀態標志,存儲器類型以及寫/讀端口的寬高比。
主要功能和優勢:
- FIFO深度高達4,194,304字
- FIFO數據寬度從1到1024位(對于本機FIFO配置),最大4096位(對于AXI FIFO配置)
- 非對稱縱橫比(讀寫端口比率范圍為1:8至8:1)
- 支持獨立或通用時鐘域
- 可選的存儲器類型(塊RAM,分布式RAM,移位寄存器或內置FIFO)
- 本機或AXI接口(AXI4,AXI4-Lite或AXI4-Stream)
- 同步或異步重置選項
- 支持分組模式
- 支持某些配置的糾錯(ECC)和注入功能
- 支持首字直通(FWFT)
- 支持用于Block RAM和基于內置FIFO原語的實現的Embedded Register選項
- 支持–空/滿,幾乎空/滿和可編程的空/滿信號
二. IP產品手冊
可參考Xilinx官網fifo_generator文檔
可下載PG057 - FIFO Generator v13.2 Product Guide (v13.2)。
三. IP框圖與信號端口
XILINX的FIFO Generator IP提供了三種接口的FIFO,分別是Native,AXI Memory Mapped 以及 AXI Sream,我個人只用過Native即普通FIFO,所以下文只介紹這一種FIFO類型。
3.1 IP模塊框圖(普通FIFO)
3.2 IP信號列表
| wr_clk | 1 | 必須 | 寫時鐘,提供給寫端口使用的時鐘 |
| wr_en | 1 | 必須 | 寫使能,高有效, 在每個寫時鐘上升沿被捕捉,捕捉一次寫入一次數據 |
| full | 1 | 必須 | 滿信號,高有效, 在FIFO內部寫數據個數 = FIFO寫深度的第一個時鐘上升沿置高, 在FIFO內部寫數據個數 < FIFO寫深度的第一個時鐘上升沿拉低。 在full有效時,FIFO會關閉寫功能,如果此時wr_en有效,full會置高overflow即輸出滿溢信號,FIFO中的數據沒有變化,往滿FIFO中寫不是破壞性的。 |
| din | 1, 2, … , 1024 | 必須 | 寫入的數據,當wr_en高被捕捉時,din被寫入到FIFO中 |
| almost_full | 1 | 可選 | 快滿信號,高有效, 在FIFO內部寫數據個數 = FIFO深度 - 1的第一個寫時鐘上升沿置高, 在FIFO內部寫數據個數 < FIFO深度 - 1的第一個寫時鐘上升沿拉低 |
| prog_full | 1 | 可選 | 設定滿信號,高有效, 參考4.3.3 Programmable Flags —— 可編程標志 |
| wr_rst | 1 | 可選 | 寫復位,高有效, 在寫復位信號有效后的第一個寫時鐘上升沿,FIFO被清空,并不再響應寫使能, 直到寫復位信號失效后下一個寫時鐘上升沿(包括)開始再去響應寫使能 |
| – | – | – | – |
| rd_clk | 1 | 可選 | 讀時鐘, 對于同步FIFO,FIFO讀寫時鐘合一 對于異步FIFO,FIFO會有分開的寫時鐘和讀時鐘 |
| rd_en | 1 | 必須 | 讀使能,高有效,在每個讀時鐘上升沿被捕捉,捕捉一次讀出一次數據 |
| empty | 1 | 必須 | 空信號,高有效, 在FIFO內部讀數據個數 = 0的第一個讀時鐘上升沿置高, 直到FIFO內部讀數據個數 > 0的第一個讀時鐘上升沿拉低。 在empty有效時,FIFO會關閉讀功能,如果此時rd_en有效,FIFO會置高underflow即輸出空溢信號,FIFO內部的數據沒有變化,讀取空FIFO不是破壞性的。 |
| dout | 可設定位寬 = din位寬 *(1/8,1/4,1/2,1,2,4,8) | 必須 | 讀數據,讀數據位寬 * 讀深度 = FIFO容量 = 寫數據位寬 * 寫深度, 對于FWFT FIFO,dout預先有效,在讀使能被捕捉的同時更新下一個讀數據, 對于標準FIFO,在讀使能被捕捉的時鐘過后的第二個時鐘上升沿,dout才是讀出的數據 |
| almost_empty | 1 | 可選 | 快空信號,高有效, 在FIFO內部讀數據個數 = 1的第一個讀時鐘上升沿置高, 在FIFO內部讀數據個數 > 1的第一個讀時鐘上升沿被拉低 |
| prog_empty | 1 | 可選 | 設定空信號,高有效, 參考4.3.3 Programmable Flags —— 可編程標志 |
其它信號很少使用,這里不做介紹。
3.3 設計注意事項
3.3.1 rst —— 復位
在FPGA配置完成后,讀寫操作開始之前,FIFO必須被復位,有同步/異步兩種復位可用。
3.3.2 clk —— 時鐘
Xilinx建議,不要通過改變clk來改變FIFO的讀寫行為,而應該去控制讀寫使能信號,當時鐘未穩定時,不要去操作FIFO,當時鐘穩定后,先對FIFO進行復位,然后再去操作FIFO。
3.3.2 wr_en 和 rd_en
雖然寫滿和讀空行為都不是破壞性的,但仍然強烈建議不要在FIFO滿時置高寫使能,不要在FIFO空時置高讀使能。也就是wr_en的用戶邏輯需要考慮full信號,rd_en的用戶邏輯需要考慮empty信號。
四. IP配置
4.1 Basic
4.1.1 FIFO接口類型
最常用的就是Native接口類型的FIFO,即普通FIFO。
4.1.2 FIFO實現
FIFO實現有兩個方面的含義:
① FIFO時鐘,公共時鐘就是同步FIFO,此時讀寫操作共用一個時鐘;獨立時鐘就是異步FIFO,此時寫操作用寫時鐘,讀操作用讀時鐘。
當選擇異步FIFO時,會出現Synchronization stages —— 同步級數的選項,此選項的意思是,當FIFO中寫入數據后,empty信號并不會立刻拉低,因為寫入數據是基于寫時鐘的,而empty信號是基于讀時鐘的,如果Synchronization stages設定為2,則意味著empty會在FIFO中寫入數據成功后的2個讀時鐘周期后拉低。選3就是3個讀時鐘周期后,以此類推。
最小的Synchronization stages值通常和具體的器件型號有關,器件頻率越快,則此選項最小選值越大,例如200MHz器件最低可以選2,而400MHz器件最低只能選4。這也告訴我們,速度越快,跨時鐘域的同步越可能不穩定,需要更多級數的D觸發器。
總的來說,Synchronization stages貌似是一個不那么關鍵的參數,通常不需要修改。
② 存儲類型,有以下四種:
1)Block RAM,塊RAM,簡稱BRAM,是在FPGA內部嵌入的硬核存儲器,BRAM數量是衡量FPGA性能的重要指標,采用BRAM做FIFO是性能最優的,但一個BRAM是18Kb,即使FIFO容量很小,也最少使用一個BRAM,這就造成了存儲容量的浪費。
2)Distributed RAM,分布式RAM,是使用FPGA內部的LUT即查找表資源搭建的FIFO,它的性能不及BRAM FIFO,但好處是它容量可以很靈活的配置,需要多少容量就用多少LUT去搭建,不會存在容量浪費的情況。
3)Shift Register,移位寄存器,此存儲類型只支持公共時鐘,沒用過。
4)Built-in FIFO,內置FIFO,沒用過。
說明,BRAM和分布式RAM是創建FIFO最常選用的存儲類型,一般來說,FIFO容量超過1024個字節就考慮使用BRAM,沒超過1024字節選擇分布式RAM。當然,如果芯片BRAM資源很富余的話,全部采用BRAM也是可以的。后兩種基本用不到。
4.1.3 FIFO支持的功能
不同的芯片型號與不同的實現形式的FIFO會支持不同的功能,不必去記憶這些,在Basic界面會將對應實現的功能展示出來。功能含義如下:
(1)non-symmetric aspect ratios(different read and write data widths),非對稱縱橫比 即 不同的寫入與讀取數據位寬,支持此功能允許讀取數據位寬與寫入數據位寬不同,具體的讀取位寬可為輸入位寬的1/8,1/4,1/2,1倍,2倍,4倍 或 8倍,當然位寬必須是整數,例如寫入數據位寬=3時,讀取數據位寬就只能取3,6,12,24。
(2)First-Word Fall-Through,首字直通,簡稱FWFT。FIFO按是否支持此功能分別兩種:
1)Standard FIFO,標準FIFO,寫入在wr_en有效的第一個wr_clk時鐘上升沿完成。讀數據時,rd_en有效,rdata端口經過幾個讀時鐘周期的延遲才裝載完成最外側讀數據,具體延遲周期數跟FIFO設置有關,下面會講到。
2)FWFT FIFO,首字直通FIFO,寫入和標準FIFO完全相同,但FWFT FIFO會將讀數據預先就裝載到rdata端口上,rd_en并不是控制FIFO去輸出讀數據,而是控制FIFO去更新下一個讀數據到rdata端口上。
通常來說,FWFT FIFO是更易使用的,讀取無延遲的優勢使得讀時序很容易控制。
(3) Uses Bulit-in FIFO primitives,使用內置FIFO原語。
(4)ECC support,ECC是Error Injection and Correction的簡稱,意思是錯誤注入和糾正。
(5)Dynamic Error Injection,動態錯誤注入。
4.1.4 Using Block RAM FIFOs Versus Built-in FIFOs,BRAM FIFO與 內置FIFO使用對比
參考手冊16頁:
內置FIFO解決方案旨在利用內置FIFO宏內部的邏輯。對于快滿,快空以及其它幾個特性,內置FIFO沒有實現,因為它們不是宏的原生特性,需要額外邏輯來實現。
手冊中寫道:基準測試表明,采用內置FIFO + 外部邏輯實現宏的非原生特性 的解決方案與直接使用BRAM FIFO相比,邏輯資源消耗小的優勢在減弱。特別是對于大容量的FIFO,BRAM更具優勢,所以我們強烈建議,當需要FIFO具備內置FIFO的非原生特性時,采用BRAM的實現形式而不是內置FIFO。
4.2 Native Ports
4.2.1 Read Mode —— 讀取模式
選擇標準FIFO與FWFT FIFO,推薦總是使用FWFT FIFO。
4.2.2 Data Port Parameters —— 數據端口參數
選擇寫位寬與寫深度,以及讀位寬與讀深度。只有支持讀寫位寬不一致功能的FIFO,讀位寬才是可選的,不支持此功能的話,讀位寬必須等于寫位寬。
4.2.3 ECC,Output Register and Power Gating Options —— 錯誤注入與糾正,輸出寄存器 和 功率控制選項
ECC:只有BRAM FIFO 和 內置FIFO支持ECC功能,
Output Register:輸出寄存器,勾選此選項意思是在輸出端口再插入寄存器,插入寄存器會增加輸出延遲,這點在設計讀取時序時需要特別注意。共有三種輸出寄存器可以選擇:
1)Embedded Registers,嵌入式寄存器
2)Fabric Registers,光纖寄存器
3)Embedded Reg And Fabric Reg,嵌入式寄存器 + 光纖寄存器
Power Gating:功率控制,只有UltraScale類型芯片的built-in FIFO才支持功率控制功能。當勾選Dynamic Power Gating(動態功率控制)時,輸入端口會增加一個sleep信號,當sleep信號高有效時,FIFO會進入省電模式,省電模式禁止寫和讀,此時wr_en與rd_en都應該為低,FIFO保留內部的數據不改變,直到sleep低電平失效。
Initialization:初始化,其實就是復位,復位總是高電平有效,無法修改FIFO的復位電平。同步FIFO支持同步復位和異步復位,而異步FIFO只支持異步復位。
異步復位可控制full信號在復位期間的值。可配置復位期間讀數據端口的值,不配置的話讀數據端口默認為0。
Read Latency:讀延遲,只有標準FIFO才有讀延遲,且會受Output Register的配置影響;FWFT FIFO讀延遲始終為0。
4.3 Status Flags
4.3.1 Optional Flag —— 可選標志
Almost Full Flag:快滿信號,高有效,在FIFO內部寫數據個數 >= FIFO深度 - 1之后的第一個寫時鐘上升沿置高,直到FIFO內部寫數據個數 < FIFO深度 - 1后的第一個寫時鐘上升沿拉低。
Almost Empty Flag:快空信號,高有效,在FIFO內部讀數據個數 <= 1之后的第一個讀時鐘上升沿置高,直到FIFO內部讀數據個數 > 1后的第一個讀時鐘上升沿拉低。
4.3.2 Handshaking Options —— 握手選項
Write Port Handshaking:寫端口握手
Write Ackongledge:寫應答,在每次寫完成后的第一個時鐘上升沿置高/拉低(有效電平可配置),一次成功寫入對應一個寫時鐘周期的寫應答。
Overflow:滿溢出,在FIFO滿之后仍有wr_en信號使能的第一個時鐘上升沿置高/拉低(有效電平可配置),一次滿溢出有效電平持續一個寫時鐘。
Read Port Handshaking:讀端口握手
Valid Ackongledge:數據有效應答,在每次讀完成后的第一個時鐘上升沿置高/拉低(有效電平可配置),一次成功讀取對應一個讀時鐘周期的數據有效應答。
Underflow:空溢出,在FIFO空之后仍有rd_en信號使能的第一個時鐘上升沿置高/拉低(有效電平可配置),一次空溢出有效電平持續一個讀時鐘。
4.3.3 Programmable Flags —— 可編程標志
Programmable Full Type:可編程滿類型,有五個選項可選:
No Programmable Full Threshold:無可編程滿臨界點
Single Programmable Full Threshold Constant:單個可編程滿臨界點常量
Multiple Programmable Full Threshold Constant:雙向可編程滿臨界點常量
Single Programmable Full Threshold Input Port:單個可編程滿臨界點輸入端口
Multiple Programmable Full Threshold Input Port:雙向可編程滿臨界點輸入端口
下面是Programmable Full Type:可編程空類型,同理,不再贅述。
可編程滿標志的產生邏輯:
當FIFO中的寫數據 >= Full Therhold Assert Value中規定的數據量(取值范圍:13 ~ 寫入深度-1)時,可編程滿置高;
當FIFO中的寫數據 <= Full Therhold Negate Value中規定的數據量(取值范圍:12 ~ Full Therhold Assert Value中的值-1)時,可編程滿拉低。
可編程空標志的產生邏輯:
同理,取值范圍需要注意:
Empty Therhold Assert Value的范圍:4 ~ 讀取深度-3;
Empty Therhold Negate Value的范圍:Empty Therhold Assert Value+1 ~ 讀取深度-2。
4.4 Data Counts
同步FIFO對應 Data Count,異步FIFO對應 Write Data Count 以及 Read Data Count。
Data count的位寬是可選的,當選擇標準FIFO時,范圍是1 ~ log2(數據深度);當選擇FWFT FIFO時,范圍是1 ~ log2(數據深度)+1。舉例說明:
如果數據深度 = 16,Data count位寬選擇4,那顯然Data count的取值范圍是0~15,這意味著計數最多記到15,當FIFO滿時計數應該是16,但這最后一個數不會被記。如果此時Data count位寬選為3,那么Data count可表示的數是0~7,那么FIFO中數據量 = 2,Data count才會加1,數據量 = 4,Data count才會加2,也就是說Data count被低位截斷了;如果此時Data count位寬選為1,那所有低位都被截斷了,意味這FIFO中數據量 = 8,Data count才會加1。
如果勾選More Accurate Data Counts(精確計數),位寬變為1~5可選,5位寬最大可表示31,前面選的FIFO深度是16,意味著FIFO滿時的最后計數16也會被記入。還有一點,選擇FWFT FIFO時,FIFO的實際深度會大于設定的深度,如上面Native Ports界面的圖所示,設定深度16而FWFT FIFO的實際深度是17,精確計數可以計數到實際深度17,這就是精確計數的概念。
當選擇同步FWFT FIFO時,默認就應用了精確計數,而無需手動選擇。
還需要說明的是,計數是有延遲的,不是FIFO中數據量一改變,計數值馬上改變的,這個延時的周期數和器件有關。
另外,計數通常只適用于調試,調試結束后就不在需要了,應該計數會增加額外的資料消耗,而且計數到某一個值的功能可以由可編程滿/空信號來代替,顯然單比特的信號更易接收和使用。
4.5 Summary
五. IP仿真
仿真框圖:
對于以下關心的問題分別仿真:
5.1 復位是否會清空FIFO,清空需要多長時間?
仿真顯示:對于同步,復位置高后,會在下一個時鐘上升沿清空FIFO;對于異步復位則是立即清空FIFO,無需等待時鐘上升沿。復位還會同時置高full和empty。
5.2 復位結束后FIFO能馬上進行寫和讀嗎?不能的話需要間隔多少時鐘周期?
上圖顯示,復位結束后即rst=0后,full信號還會一直為高持續多個周期,此時FIFO不能寫也不能讀(沒有數據),這個持續周期數對于16深度的FIFO是13個寫時鐘周期,對于深度32的FIFO還是13個寫時鐘周期,對于深度1024的FIFO是14個寫時鐘周期,可見FIFO從復位結束到恢復讀寫功能需要大約13個寫時鐘周期。
5.3 FWFT FIFO的實際深度會大于設定深度,那么full和almost_full信號是當數據量達到設定深度置高,還是達到實際深度才置高?
對于設定深度16,實際深度17的FWFT FIFO,almost_full在寫入16個數據后置高,full在寫入17個數據后置高,所以滿信號是以實際深度為準的。
5.4 FIFO寫入一個數據后,多久empty會失效?
仿真結果顯示:寫入第一個數據后,經過8個讀時鐘周期,empty才拉低。
5.5 可編程滿和可編程空的產生邏輯是什么?
確實如4.3.3 Programmable Flags —— 可編程標志節描述的一致,不好展示,讀者可自行仿真驗證。
六. FIFO使用建議
1.總是使用FWFT FIFO,無延遲的讀便于控制
2.資源足夠時總是使用BRAM FIFO;資源緊張時,小型FIFO可使用分布式FIFO
3.FIFO在使用之前必須復位,復位時置高full,禁止一切讀寫操作
4.在產生wr_en信號時,必須和~full信號進行與操作,且必須是組合邏輯,因為時序邏輯會延遲一個寫時鐘才起作用,可能造成寫滿的情況發生,示例代碼如下:
reg wr_en_temp; always @(posedge clk) beginif (~rstn)wr_en_temp <= 1'b0;else if (data_valid)wr_en_temp <= 1'b1;elsewr_en_temp <= 1'b0;assign wr_en = ~full && wr_en_temp;5.與產生wr_en同理,產生rd_en信號時,必須和~empty信號進行與操作,且必須是組合邏輯,防止讀空的情況發生,示例代碼如下:
reg rd_en_temp; always @(posedge clk) beginif (~rstn)rd_en_temp <= 1'b0;else if (ready)rd_en_temp <= 1'b1;elserd_en_temp <= 1'b0;assign rd_en = ~empty && rd_en_temp;七. 工程分享
Xilinx IP解析——FIFO Generator V13.2 Vivado 2021.2工程:
鏈接:https://pan.baidu.com/s/1FIqZx29V2zkiqfib380amw
提取碼:q9fs
總結
以上是生活随笔為你收集整理的Xilinx IP解析之FIFO Generator v13.2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的Python脚本——生成任意波形并存
- 下一篇: Python学会使用虚拟环境——pipe