IP核之初——FIFO
本文設計思路源自明德揚至簡設計法。在之前的幾篇博文中,由於設計比較簡單,所有的功能都是用verilogHDL代碼編寫實現的。我們要學會站在巨人的肩膀上,這時候就該IP核登場了!
說白了,IP核就是別人做好了的硬件模塊,提供完整的用戶接口和說明文檔,更復雜的還有示例工程,你只要能用好這個IP核,設計已經完成一半了。說起來容易,從冗長的英文文檔和網上各個非標準教程中汲取所需,並靈活運用還是需要下一番功夫的。
我認為其中最重要的幾點如下:
1) 提供給IP核正確的時鐘和復位條件;
2) 明確各個重要用戶接口功能;
3) 掌握所需指令的操作時序;
4) 知道內部寄存器地址及功能和配置方式、順序;
5) 會從官方示例工程中學會IP核正確使用方式;
今天來講講一個最常用的IP核,FIFO。可以說它是FPGA能如此靈活處理數據的基礎,常用於異步時鐘域處理、位寬轉換以及需要數據緩存的場合。先來說明下,對於初學者和剛接觸一個IP核的人來說,不要過分關註IP核的每一個參數和功能,更沒必要知道內部的具體結構和工作原理(還沒忘之前使用的ILA吧,反正我是不知道具體怎麽設計出來的)只需掌握最常用的和最重要的,把IP核用起來就大功告成了。先從生成IP核開始吧:
配置向導中第一頁中是選擇FIFO的接口模式和實現方式。這裏我們用原始的接口方式。箭頭處是實現方式,如果需要異步時鐘域處理選擇讀寫獨立時鐘模式。
第二頁中需要特意強調的是讀模式的選擇。其實這裏的First Word Fall Through對應的就是Altera FPGA中FIFO IP核讀模式中的Show ahead模式嘛,換個名字而已。這個讀模式的特點是在讀使能有效之前,即把FIFO中第一個數據從讀數據端口持續送出。在這種模式下,讀使能信號倒像是“讀清”信號,把上一次的數據清除掉,讓FIFO送出下一個數據。這樣做的處是符合dout 和dout_vld相配合的輸出信號方式。(不懂的先記下,後面會舉例闡述)
第三頁是配置一些可選的標誌位,可以根據需要靈活實現一些標誌位和握手特性(我是從來沒用過)。
第四頁可選FIFO內緩存數據量計數器,由於我開始選擇的是異步FIFO模式,所以此處有兩個計數器分別與讀側和寫側時鐘上升沿同步。註意一點:這兩個計數器均表示FIFO緩存數據量,只不過在時鐘上有些偏差,切不可錯誤理解為是寫入了或者讀出了多少個數據。
最後總結頁,把前邊的參數和配置匯總下。沒有問題可以點擊OK了!
IP核生成好了,接下來要正確用起來。我們把以太網接口數據傳輸作為案例背景,通常來說是FPGA邏輯+MAC IP核+外部PHY芯片的架構。若想讓MAC IP核正確接收待發送數據,需要將數據進行封包並加入MAC頭部信息。
為簡化設計,先只考慮對封包後數據添加MAC頭部的功能,也就是說此時輸入的數據即是長度符合以太網規範,且具有數據包格式的數據。由於在數據部分輸出前加額外的信息,所以先要緩存輸入的數據直到MAC頭輸出完成再將寫入數據發送出來,因此需要用FIFO緩存數據。進一步分析,經過分包後的數據格式如下:
其中sop和eop分別是包頭,包尾指示信號,data_vld是數據有效指示信號。為了讓該模塊輸出端知道何時輸出完一個數據包,要把eop信號和數據信號拼接寫入FIFO中,這樣輸出端發出eop時進入新一輪循環。如果根據寫入sop信號來作為開始發送MAC頭部和數據部分的標誌,試想當一個短包緊跟著一個長包寫進FIFO中時,輸出端正在送出上一長包剩下的幾個數據,無法響應短包的sop信號指示,那麽短包即被“丟棄”了。為了避免丟包現象,需要滿足“讀寫隔離規則”,即FIFO讀操作和寫操作兩者不能根據一方的情況來決定另一方的行為。進一步引出“雙FIFO架構”,使用數據FIFO緩存數據,而信息FIFO保留指示信息,這樣講寫側的指示信號寫入信息FIFO中,數據FIFO可以根據信息FIFO讀側的信息來判斷讀的行為,也就滿足了讀寫隔離規則。
在該模塊中,可以在寫側出現sop信號時寫入信息FIFO一個指示信息,所以當信息FIFO非空即表示有一個數據包正在進來,此時發送MAC頭信息,隨之讀取數據FIFO中緩存數據,當讀側出現eop信號則讀清信息FIFO,循環往復完成了添加頭部信息的工作。
有了項目需求,設計思路後明確模塊接口列表:
現在開始編寫代碼了:
IP核之初——FIFO