【小月电子】ALTERA FPGA开发板系统学习教程-LESSON12 IPCORE核之FIFO详细教程
ALTERA FPGA IPCORE核之FIFO詳細教程
若要觀看該博客配套的視頻教程,可點擊此鏈接
一. FIFO簡介
FIFO: 是英文first in first out的縮寫,即先進先出,指的是對數據的存儲具有先進先出特性的緩存器。從字面意思上就可以大致看出和RAM和ROM的區別,即沒有地址線,無法像RAM和ROM一樣寫入或讀出指定地址的數據,而必須按順序讀出。
根據讀寫操作是否使用同一個時鐘,可以將FIFO分為兩類:
-
同步FIFO
讀寫操作使用同一個時鐘,一般用于數據緩存
-
異步FIFO
讀寫操作使用不同的時鐘,一般用于跨時鐘域處理,比如我們在做視頻相關項目時,假如我們的攝像頭的像素時鐘是25MHZ,SDRAM的讀寫時鐘是100MHZ,那我們要把采集到的視頻數據寫入SDRAM,那么就必須要用到異步FIFO,進行跨時鐘域處理。還有一種應用場景,讀寫數據的位寬不一致時,比如寫入的數據是16位,讀出的數據需要8位,這時候使用異步FIFO,只需要分別選擇寫數據位寬和讀數據位寬,非常方便,值得注意的是QuartusII中的同步FIFO,讀數據位寬是無法進行更改,默認和寫數據位寬一致。
二. FIFO IPCORE生成步驟及參數介紹
不同公司的FPGA,生成的FIFO大同小異,本篇我們以一個實例來對ALTERA的IPCORE來進行介紹。我們要生成一個寫數據位寬8,讀數據位寬16的異步FIFO,利用Modelsim仿真來觀察FIFO的時序波形。
2.1 首先打開QuartusII軟件,新建一個工程,命令為async_fifo_test
新建QuartusII工程的步驟就不一一說明,為了方便上板驗證,選用我們開發板上的器件:EP4CE6F17C8
2.2 FIFO IPCORE配置
2.2.1 生成IPCORE,命名為async_fifo_w8r16_d1024
我們在對IPCORE命名時,最好能體現出該IPCORE的一些主要特性,比如我們上面的命令,我們知道是一個異步FIFO,寫數據位寬8,讀數據位寬16,深度1024。說到這,就有必要說一下非對稱讀寫位寬。讀寫數據的位寬可以不一致,但是必須滿足比例關系:1:8,1:4,1:2,1:1,那么讀寫位寬不一致,數據的排序關系是怎么樣的呢?我們分兩種情況做一下說明:
寫位寬大于讀位寬,直截了當我做了一個簡單的測試程序仿真出的波形如下:
通過仿真可以看出,寫入16’h0102,先讀出的是8’h02,接著讀出的是8’h01,是不是和我們想的不一樣,所以這個地方一定要注意噢
寫位寬小于讀位寬,直截了當我做了一個簡單的測試程序仿真出的波形如下:
通過仿真可以看出,寫入8’h01,8’h02兩個數,讀出的是16’h0201,是不是和我們想的不一樣,所以這個地方一定要注意噢
2.2.2 生成FIFO的步驟如下圖所示:
當我們生成好后可以看到左邊FIFO框圖上顯示了FIFO的輸入輸出接口,左下角是FIFO使用的FPGA內部資源。
2.2.2 FIFO各接口定義如下:
1. wrfull:選用寫時鐘域,寫滿是指寫得快讀得慢,FIFO里面的存儲數據超過了FIFO的深度,如果這時候再繼續寫,數據就會溢出丟失,所以這時需要禁止再往FIFO 中寫入數據,防止數據溢出丟失。高電平表示FIFO寫入數據量達到 FIFO 設置的最大空間
2. rdempty:選用讀時鐘域,高電平表示 FIFO 中已經沒有數據了,此時應該通過該信號控制讀請求信號(也稱為讀使能信號),禁止FIFO 繼續再讀出數據,否則讀出的將是無效數據。
3. rdusedw:為FIFO里面存存儲的數據個數。在某些應用場景下,我們需要用到usedw時鐘監測FIFO存儲的數據個數,但是需要注意,同步FIFO的數據計數是準確的,因為讀寫時鐘相同,不需要做跨時鐘域處理;但是異步FIFO的計數就不準確了,只能粗略的進行判斷,比如半空,半滿等。
4. wrreq:寫使能,高電平有效
5. wrclk:寫時鐘
6. data:寫數據,位寬8
7. rdreq:讀使能,高電平有效
8. rdclk:讀時鐘
9. aclr:異步復位信號,用于清空 FIFO
10. almost full:幾乎滿標志信號,我們可以控制 FIFO 快要被寫滿的時候和 full 信號的作用一樣。
11. almost empty:幾乎空標志信號,我們可以控制 FIFO 快要被讀空的時候和 empty 信號的作用一樣。
12. Synchronous clear:同步復位信號,用于清空 FIFO。
10~12的信號,本例程的FIFO沒有生成,大家可根據具體需求選擇是否生成這些信號。
三. Verilog代碼設計
`timescale 1ns / 100psmodule async_fifo_test(input clk ,//50MHZinput rst_n ,output [15:0] dout);reg [ 7:0] fifo_wdata ;reg fifo_wren ;reg fifo_rden ;wire[15:0] fifo_rdata ;wire fifo_wclk ;wire fifo_rclk ;wire locked ;reg [9:0] wr_cnt ;reg [8:0] rd_cnt ;assign dout=fifo_rdata ;//注意需要在fifo_wclk時鐘域下,因為fifo寫使能和寫數據都是在該計數器(wr_cnt)下生成always@(posedge fifo_wclk or negedge locked)beginif(!locked)wr_cnt<=0;else wr_cnt<=wr_cnt+1;end//注意需要在fifo_rclk時鐘域下,因為fifo讀使能是在該計數器(rd_cnt)下生成always@(posedge fifo_rclk or negedge locked)beginif(!locked)rd_cnt<=0;else rd_cnt<=rd_cnt+1;end//在fifo_wclk時鐘域下生成FIFO寫數據和寫使能,位寬8位,寫100個數據always@(posedge fifo_wclk or negedge locked)beginif(!locked)beginfifo_wren<=0;fifo_wdata<=0;end else if(wr_cnt>0&&wr_cnt<=100)beginfifo_wren<=1;fifo_wdata<=fifo_wdata+1;end else beginfifo_wren<=0;endend//在fifo_rclk時鐘域下生成FIFO讀使能,讀數據的位寬是16位,所以讀50個數據就將FIFo讀空always@(posedge fifo_rclk or negedge locked)beginif(!locked)fifo_rden<=0;else if(rd_cnt>100&&rd_cnt<=150)fifo_rden<=1;elsefifo_rden<=0;end//利用PLL生成FIFO的讀寫時鐘,寫時鐘25MHZ,讀時鐘50MHZpll Upll(.areset (~rst_n ),.inclk0 (clk ),.c0 (fifo_wclk ),.c1 (fifo_rclk ),.locked (locked ));//例化FIFO IPCOREasync_fifo_w8r16_d1024 Uasync_fifo_w8r16_d1024(.aclr (~rst_n ),//復位,高電平復位.data (fifo_wdata ),//寫數據.rdclk (fifo_rclk ),//讀時鐘.rdreq (fifo_rden ),//讀使能.wrclk (fifo_wclk ),//寫時鐘.wrreq (fifo_wren ),//寫使能.q (fifo_rdata ),//讀數據.rdempty (),//讀空標志.rdusedw (),//在讀時鐘域下,FIFO中當前存儲的數據個數,數據位寬16位.wrfull ()//寫滿標志);endmodule四. Verilog測試代碼設計
`timescale 1ns / 100psmodule async_fifo_test_tb;reg clk =1;reg rst_n =0;initialbegin#1000rst_n=1;end//生成激勵時鐘always #10 clk<=~clk;//例化被測試模塊async_fifo_test Uasync_fifo_test(.clk (clk ),//50MHZ.rst_n (rst_n ),.dout ( ));endmodule五. 仿真波形分析
1.aclr :fifo復位信號,高電平復位
2.wrclk :fifo寫時鐘
3.wrreq :fifo寫使能,高電平時表示寫入數據。
4.rdclk :fifO讀時鐘
5.rdreq :fifo讀使能,高電平表示讀數據,由于我們選擇是正常模式,所以在rdreq有效時,會延時一個時鐘周期才會出有效數據。
6.q:fifo讀數據
7.rdempty:空標志,高電平表示fifo為空,在仿真波形中可以看出在fifo復位時且未寫入數據時,rdempty為高電平,當前fifo為空。
8.rdusedw:FIFO里面存存儲的數據個數,由于我們用的是異步fifO,這個數據并不能精確的反應fifo里面的數據個數,只能做一個參考。通過上面的仿真圖也可以看出,rdusedw并沒有精確的反應fifo中的數據個數。
9.wrfull:滿標志,當fifo中存儲的數據個數超過fifo自身的深度時,便會溢出,wrful置高。
通過上面的仿真圖,我們可以看到wrfull一直為低,所以fifo數據未溢出,不會造成數據丟失。同時,fifo在進行讀操作時,rdempty一直為低,說明在讀數據時,fifo中一直有數據,不會讀出無效數據。一般來說,只要fifo操作滿足以上兩個條件,便可進行正常的數據寫入和讀取。
如果大家想要該工程的源碼和仿真測試激勵文件用來學習,可以直接聯系工程師,謝謝大家的閱讀!
總結
以上是生活随笔為你收集整理的【小月电子】ALTERA FPGA开发板系统学习教程-LESSON12 IPCORE核之FIFO详细教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信语音内容怎么录制,电脑如何内录
- 下一篇: 保证一个用户已选取的记录不被其他用户选取