【ZYNQ Ultrascale+ MPSOC FPGA教程】第八章FPGA片內(nèi)FIFO讀寫測(cè)試實(shí)驗(yàn)
資料介紹
作者: ALINX
* 本原創(chuàng)教程由芯驛電子科技(上海)有限公司(ALINX)創(chuàng)作,版權(quán)歸本公司所有,如需轉(zhuǎn)載,需授權(quán)并注明出處。
適用于板卡型號(hào):
AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E/AXU4EV-P/AXU5EV-E/AXU5EV-P /AXU9EG/AXU15EG
實(shí)驗(yàn)Vivado工程為“fifo_test”。
FIFO是FPGA應(yīng)用當(dāng)中非常重要的模塊,廣泛用于數(shù)據(jù)的緩存,跨時(shí)鐘域數(shù)據(jù)處理等。學(xué)好FIFO是FPGA的關(guān)鍵,靈活運(yùn)用好FIFO是一個(gè)FPGA工程師必備的技能。本章主要介紹利用XILINX提供的FIFO IP進(jìn)行讀寫測(cè)試。
1.實(shí)驗(yàn)原理
FIFO: First in, First out代表先進(jìn)的數(shù)據(jù)先出,后進(jìn)的數(shù)據(jù)后出。Xilinx在VIVADO里為我們已經(jīng)提供了FIFO的IP核, 我們只需通過(guò)IP核例化一個(gè)FIFO,根據(jù)FIFO的讀寫時(shí)序來(lái)寫入和讀取FIFO中存儲(chǔ)的數(shù)據(jù)。
其實(shí)FIFO是也是在RAM的基礎(chǔ)上增加了許多功能,F(xiàn)IFO的典型結(jié)構(gòu)如下,主要分為讀和寫兩部分,另外就是狀態(tài)信號(hào),空和滿信號(hào),同時(shí)還有數(shù)據(jù)的數(shù)量狀態(tài)信號(hào),與RAM最大的不同是FIFO沒(méi)有地址線,不能進(jìn)行隨機(jī)地址讀取數(shù)據(jù),什么是隨機(jī)讀取數(shù)據(jù)呢,也就是可以任意讀取某個(gè)地址的數(shù)據(jù)。而FIFO則不同,不能進(jìn)行隨機(jī)讀取,這樣的好處是不用頻繁地控制地址線。
雖然用戶看不到地址線,但是在FIFO內(nèi)部還是有地址的操作的,用來(lái)控制RAM的讀寫接口。其地址在讀寫操作時(shí)如下圖所示,其中深度值也就是一個(gè)FIFO里最大可以存放多少個(gè)數(shù)據(jù)。初始狀態(tài)下,讀寫地址都為0,在向FIFO中寫入一個(gè)數(shù)據(jù)后,寫地址加1,從FIFO中讀出一個(gè)數(shù)據(jù)后,讀地址加1。此時(shí)FIFO的狀態(tài)即為空,因?yàn)閷懥艘粋€(gè)數(shù)據(jù),又讀出了一個(gè)數(shù)據(jù)。
可以把FIFO想象成一個(gè)水池,寫通道即為加水,讀通道即為放水,假如不間斷的加水和放水,如果加水速度比放水速度快,那么FIFO就會(huì)有滿的時(shí)候,如果滿了還繼續(xù)加水就會(huì)溢出overflow,如果放水速度比加水速度快,那么FIFO就會(huì)有空的時(shí)候,所以把握好加水與放水的時(shí)機(jī)和速度,保證水池一直有水是一項(xiàng)很艱巨的任務(wù)。也就是判斷空與滿的狀態(tài),擇機(jī)寫數(shù)據(jù)或讀數(shù)據(jù)。
根據(jù)讀寫時(shí)鐘,可以分為同步FIFO(讀寫時(shí)鐘相同)和異步FIFO(讀寫時(shí)鐘不同)。同步FIFO控制比較簡(jiǎn)單,不再介紹,本節(jié)實(shí)驗(yàn)主要介紹異步FIFO的控制,其中讀時(shí)鐘為75MHz,寫時(shí)鐘為100MHz。實(shí)驗(yàn)中會(huì)通過(guò)VIVADO集成的在想邏輯分析儀ila,我們可以觀察FIFO的讀寫時(shí)序和從FIFO中讀取的數(shù)據(jù)。
2. 創(chuàng)建Vivado工程
2.1 添加FIFO IP核
在添加FIFO IP之前先新建一個(gè)fifo_test的工程, 然后在工程中添加FIFO IP,方法如下:
2.1.1點(diǎn)擊下圖中IP Catalog,在右側(cè)彈出的界面中搜索fifo,找到FIFO Generator,雙擊打開(kāi)。
2.1.2 彈出的配置頁(yè)面中,這里可以選擇讀寫時(shí)鐘分開(kāi)還是用同一個(gè),一般來(lái)講我們使用FIFO為了緩存數(shù)據(jù),通常兩邊的時(shí)鐘速度是不一樣的。所以獨(dú)立時(shí)鐘是最常用的,我們這里選擇“Independent Clocks Block RAM”,然后點(diǎn)擊“Next”到下一個(gè)配置頁(yè)面。
2.1.3 切換到Native Ports欄目下,選擇數(shù)據(jù)位寬16;FIFO深選擇512,實(shí)際使用大家根據(jù)需要自行設(shè)置就可以。Read Mode有兩種方式,一個(gè)Standard FIFO,也就是平時(shí)常見(jiàn)的FIFO,數(shù)據(jù)滯后于讀信號(hào)一個(gè)周期,還有一種方式為First Word Fall Through,數(shù)據(jù)預(yù)取模式,簡(jiǎn)稱FWFT模式。也就是FIFO會(huì)預(yù)先取出一個(gè)數(shù)據(jù),當(dāng)讀信號(hào)有效時(shí),相應(yīng)的數(shù)據(jù)也有效。我們首先做標(biāo)準(zhǔn)FIFO的實(shí)驗(yàn)。
2.1.4 切換到Data Counts欄目下,使能Write Data Count(已經(jīng)FIFO寫入多少數(shù)據(jù))和Read Data Count(FIFO中有多少數(shù)據(jù)可以讀),這樣我們可以通過(guò)這兩個(gè)值來(lái)看FIFO內(nèi)部的數(shù)據(jù)多少。點(diǎn)擊OK,Generate生成FIFO IP。
2.2 FIFO的端口定義與時(shí)序
FIFO的數(shù)據(jù)寫入和讀出都是按時(shí)鐘的上升沿操作的,當(dāng)wr_en信號(hào)為高時(shí)寫入FIFO數(shù)據(jù),當(dāng)almost_full信號(hào)有效時(shí),表示FIFO只能再寫入一個(gè)數(shù)據(jù),一旦寫入一個(gè)數(shù)據(jù)了,full信號(hào)就會(huì)拉高,如果在full的情況下wr_en仍然有效,也就是繼續(xù)向FIFO寫數(shù)據(jù),則FIFO的overflow就會(huì)有效,表示溢出。
標(biāo)準(zhǔn)FIFO寫時(shí)序
當(dāng)rd_en信號(hào)為高時(shí)讀FIFO數(shù)據(jù),數(shù)據(jù)在下個(gè)周期有效。valid為數(shù)據(jù)有效信號(hào),almost_empty表示還有一個(gè)數(shù)據(jù)讀,當(dāng)再讀一個(gè)數(shù)據(jù),empty信號(hào)有效,如果繼續(xù)讀,則underflow有效,表示下溢,此時(shí)讀出的數(shù)據(jù)無(wú)效。
標(biāo)準(zhǔn)FIFO讀時(shí)序
而從FWFT模式讀數(shù)據(jù)時(shí)序圖可以看出,rd_en信號(hào)有效時(shí),有效數(shù)據(jù)D0已經(jīng)在數(shù)據(jù)線上準(zhǔn)備好有效了,不會(huì)再延后一個(gè)周期。這就是與標(biāo)準(zhǔn)FIFO的不同之處。
FWFT FIFO讀時(shí)序
關(guān)于FIFO的詳細(xì)內(nèi)容可參考pg057文檔,可在xilinx官網(wǎng)下載。
3. FIFO測(cè)試程序編寫
我們按照異步FIFO進(jìn)行設(shè)計(jì),用PLL產(chǎn)生出兩路時(shí)鐘,分別是100MHz和75MHz,用于寫時(shí)鐘和讀時(shí)鐘,也就是寫時(shí)鐘頻率高于讀時(shí)鐘頻率。
`timescale1ns/1ps ////////////////////////////////////////////////////////////////////////////////// module fifo_test ( input clk, //25MHz時(shí)鐘 input rst_n //復(fù)位信號(hào),低電平有效 ); reg [15:0] w_data ; //FIFO寫數(shù)據(jù) wire wr_en ; //FIFO寫使能 wire rd_en ; //FIFO讀使能 wire[15:0] r_data ; //FIFO讀數(shù)據(jù) wire full ; //FIFO滿信號(hào) wire empty ; //FIFO空信號(hào) wire[8:0] rd_data_count ; //可讀數(shù)據(jù)數(shù)量 wire[8:0] wr_data_count ; //已寫入數(shù)據(jù)數(shù)量 wire clk_100M ; //PLL產(chǎn)生100MHz時(shí)鐘 wire clk_75M ; //PLL產(chǎn)生100MHz時(shí)鐘 wire locked ; //PLL lock信號(hào),可作為系統(tǒng)復(fù)位信號(hào),高電平表示lock住 wire fifo_rst_n ; //fifo復(fù)位信號(hào), 低電平有效 wire wr_clk ; //寫FIFO時(shí)鐘 wire rd_clk ; //讀FIFO時(shí)鐘 reg [7:0] wcnt ; //寫FIFO復(fù)位后等待計(jì)數(shù)器 reg [7:0] rcnt ; //讀FIFO復(fù)位后等待計(jì)數(shù)器 wire clkbuf ; BUFG BUFG_inst ( .O(clkbuf),// 1-bit output: Clock output. .I(clk)// 1-bit input: Clock input. ); //例化PLL,產(chǎn)生100MHz和75MHz時(shí)鐘 clk_wiz_0 fifo_pll ( // Clock out ports .clk_out1(clk_100M), // output clk_out1 .clk_out2(clk_75M), // output clk_out2 // Status and control signals .reset(~rst_n), // input reset .locked(locked), // output locked // Clock in ports .clk_in1(clkbuf) // input clk_in1 ); assign fifo_rst_n = locked ; //將PLL的LOCK信號(hào)賦值給fifo的復(fù)位信號(hào) assign wr_clk = clk_100M ; //將100MHz時(shí)鐘賦值給寫時(shí)鐘 assign rd_clk = clk_75M ; //將75MHz時(shí)鐘賦值給讀時(shí)鐘 /* 寫FIFO狀態(tài)機(jī) */ localparam W_IDLE =1 ; localparam W_FIFO =2 ; reg[2:0] write_state; reg[2:0] next_write_state; always@(posedge wr_clk ornegedge fifo_rst_n) begin if(!fifo_rst_n) write_state <= W_IDLE; else write_state <= next_write_state; end always@(*) begin case(write_state) W_IDLE: begin if(wcnt ==8'd79)//復(fù)位后等待一定時(shí)間,safety circuit模式下的最慢時(shí)鐘60個(gè)周期 next_write_state <= W_FIFO; else next_write_state <= W_IDLE; end W_FIFO: next_write_state <= W_FIFO; //一直在寫FIFO狀態(tài) default: next_write_state <= W_IDLE; endcase end //在IDLE狀態(tài)下,也就是復(fù)位之后,計(jì)數(shù)器計(jì)數(shù) always@(posedge wr_clk ornegedge fifo_rst_n) begin if(!fifo_rst_n) wcnt <=8'd0; elseif(write_state == W_IDLE) wcnt <= wcnt +1'b1; else wcnt <=8'd0; end //在寫FIFO狀態(tài)下,如果不滿就向FIFO中寫數(shù)據(jù) assign wr_en =(write_state == W_FIFO)?~full :1'b0; //在寫使能有效情況下,寫數(shù)據(jù)值加1 always@(posedge wr_clk ornegedge fifo_rst_n) begin if(!fifo_rst_n) w_data <=16'd1; elseif(wr_en) w_data <= w_data +1'b1; end /* 讀FIFO狀態(tài)機(jī) */ localparam R_IDLE =1 ; localparam R_FIFO =2 ; reg[2:0] read_state; reg[2:0] next_read_state; ///產(chǎn)生FIFO讀的數(shù)據(jù) always@(posedge rd_clk ornegedge fifo_rst_n) begin if(!fifo_rst_n) read_state <= R_IDLE; else read_state <= next_read_state; end always@(*) begin case(read_state) R_IDLE: begin if(rcnt ==8'd59) //復(fù)位后等待一定時(shí)間,safety circuit模式下的最慢時(shí)鐘60個(gè)周期 next_read_state <= R_FIFO; else next_read_state <= R_IDLE; end R_FIFO: next_read_state <= R_FIFO ; //一直在讀FIFO狀態(tài) default: next_read_state <= R_IDLE; endcase end //在IDLE狀態(tài)下,也就是復(fù)位之后,計(jì)數(shù)器計(jì)數(shù) always@(posedge rd_clk ornegedge fifo_rst_n) begin if(!fifo_rst_n) rcnt <=8'd0; elseif(write_state == W_IDLE) rcnt <= rcnt +1'b1; else rcnt <=8'd0; end //在讀FIFO狀態(tài)下,如果不空就從FIFO中讀數(shù)據(jù) assign rd_en =(read_state == R_FIFO)?~empty :1'b0; //----------------------------------------------------------- //實(shí)例化FIFO fifo_ip fifo_ip_inst ( .rst (~fifo_rst_n ),// input rst .wr_clk (wr_clk ),// input wr_clk .rd_clk (rd_clk ),// input rd_clk .din (w_data ),// input [15 : 0] din .wr_en (wr_en ),// input wr_en .rd_en (rd_en ),// input rd_en .dout (r_data ),// output [15 : 0] dout .full (full ),// output full .empty (empty ),// output empty .rd_data_count (rd_data_count ),// output [8 : 0] rd_data_count .wr_data_count (wr_data_count )// output [8 : 0] wr_data_count ); //寫通道邏輯分析儀 ila_m0 ila_wfifo ( .clk (wr_clk ), .probe0 (w_data ), .probe1 (wr_en ), .probe2 (full ), .probe3 (wr_data_count ) ); //讀通道邏輯分析儀 ila_m0 ila_rfifo ( .clk (rd_clk ), .probe0 (r_data ), .probe1 (rd_en ), .probe2 (empty ), .probe3 (rd_data_count ) ); endmodule
在程序中采用PLL的lock信號(hào)作為fifo的復(fù)位,同時(shí)將100MHz時(shí)鐘賦值給寫時(shí)鐘,75MHz時(shí)鐘賦值給讀時(shí)鐘。
有一點(diǎn)需要注意的是,F(xiàn)IFO設(shè)置默認(rèn)為采用safety circuit,此功能是保證到達(dá)內(nèi)部RAM的輸入信號(hào)是同步的,在這種情況下,如果異步復(fù)位后,則需要等待60個(gè)最慢時(shí)鐘周期,在本實(shí)驗(yàn)中也就是75MHz的60個(gè)周期,那么100MHz時(shí)鐘大概需要(100/75)x60=80個(gè)周期。
因此在寫狀態(tài)機(jī)中,等待80個(gè)周期進(jìn)入寫FIFO狀態(tài)
在讀狀態(tài)機(jī)中,等待60個(gè)周期進(jìn)入讀狀態(tài)
如果FIFO不滿,就一直向FIFO寫數(shù)據(jù)
如果FIFO不空,就一直從FIFO讀數(shù)據(jù)
例化兩個(gè)邏輯分析儀,分別連接寫通道和讀通道的信號(hào)
4. 仿真
以下為仿真結(jié)果,可以看到寫使能wr_en有效后開(kāi)始寫數(shù)據(jù),初始值為0001,從開(kāi)始寫到empty不空,是需要一定周期的,因?yàn)閮?nèi)部還要做同步處理。在不空后,開(kāi)始讀數(shù)據(jù),讀出的數(shù)據(jù)相對(duì)于rd_en滯后一個(gè)周期。
在后面可以看到如果FIFO滿了,根據(jù)程序的設(shè)計(jì),滿了就不向FIFO寫數(shù)據(jù)了,wr_en也就拉低了。為什么會(huì)滿呢,就是因?yàn)閷憰r(shí)鐘比讀時(shí)鐘快。如果將寫時(shí)鐘與讀時(shí)鐘調(diào)換,也就是讀時(shí)鐘快,就會(huì)出現(xiàn)讀空的情況,大家可以試一下。
如果將FIFO的Read Mode改成First Word Fall Through
仿真結(jié)果如下,可以看到rd_en有效的時(shí)候數(shù)據(jù)也有效,沒(méi)有相差一個(gè)周期
5. 板上驗(yàn)證
生成好bit文件,下載bit文件,會(huì)出現(xiàn)兩個(gè)ila,先來(lái)看寫通道的,可以看到full信號(hào)為高電平時(shí),wr_en為低電平,不再向里面寫數(shù)據(jù)。
而讀通道也與仿真一致
如果以rd_en上升沿作為觸發(fā)條件,點(diǎn)擊運(yùn)行,然后按下復(fù)位,也就是我們綁定的PL KEY1,會(huì)出現(xiàn)下面的結(jié)果,與仿真一致,標(biāo)準(zhǔn)FIFO模式下,數(shù)據(jù)滯后rd_en一個(gè)周期。
- Zynq UltraScale+ MPSoC驗(yàn)證數(shù)據(jù)手冊(cè)
- Zynq UltraScale+ MPSoC中的隔離方法
- Zynq UltraScale+ MPSoC的隔離設(shè)計(jì)示例
- IC工藝和版圖設(shè)計(jì)第八章Latch-up和GuardRing設(shè)計(jì) 0次下載
- 米爾電子zynq ultrascale+ mpsoc底板外設(shè)資源清單分享
- 【ZYNQ Ultrascale+ MPSOC FPGA教程】第六章 FPGA片內(nèi)RAM讀寫測(cè)試實(shí)驗(yàn)
- 【ZYNQ Ultrascale+ MPSOC FPGA教程】第七章 FPGA片內(nèi)ROM測(cè)試實(shí)驗(yàn)
- 如何調(diào)試 Zynq UltraScale+ MPSoC VCU DDR 控制器?
- 【ZYNQ Ultrascale+ MPSOC FPGA教程】第一章 MPSoC芯片介紹
- 電路《電路原理》邱關(guān)源---第八章 相量法 0次下載
- 《測(cè)控電路》習(xí)題完整參考答案(第八章) 0次下載
- 電子技術(shù)基礎(chǔ)模擬部分第五版_第八章習(xí)題答案.pdf 0次下載
- 51單片機(jī)第八章素材 1次下載
- 信號(hào)發(fā)生電路基礎(chǔ) 第八章
- 波形的產(chǎn)生與變換電路 第八章PPT
- 針對(duì)UltraScale/UltraScale+芯片DFX應(yīng)考慮的因素有哪些(1) 537次閱讀
- Xilinx ZYNQ UltraScale+系列產(chǎn)品介紹 2405次閱讀
- FPGAs,Zynq和Zynq MPSoC器件的特點(diǎn) 2275次閱讀
- 基于Xilinx Zynq UltraScale+ RFSoC ZCU216評(píng)估套件詳細(xì)內(nèi)容介紹 9162次閱讀
- 基于Xilinx Zynq ultraScale+ 系列FPGA的AXU2CGB 開(kāi)發(fā)板評(píng)測(cè) 9051次閱讀
- 米爾科技Zynq UltraScale+ MPSoC技術(shù)參考手冊(cè)介紹 2975次閱讀
- 詳解Xilinx公司Zynq? UltraScale+?MPSoC產(chǎn)品 3184次閱讀
- Xilinx Zynq UltraScale MPSoC可擴(kuò)展電源設(shè)計(jì) 1950次閱讀
- Xilinx Kintex UltraScale+ FPGA KCU116評(píng)估套件主要性能和優(yōu)勢(shì) 6734次閱讀
- Zynq UltraScale+ MPSoC ZCU102評(píng)估套件解決方案 8640次閱讀
- Enea OSE可實(shí)現(xiàn)對(duì)Xilinx UltraScale+ MPSoC的支持 2790次閱讀
- Xilinx基于ARM的Zynq-7000和Zynq UltraScale+ MPSoC及RFSoC器件是否存在安全漏洞 2620次閱讀
- Zynq UltraScale+ MPSoC 上的多個(gè)Linux UIO設(shè)計(jì) 3219次閱讀
- 用ZYNQ MPSoC玩DOOM! 2539次閱讀
- Ti推出面向Zynq UltraScale+ MPSoC的電源參考設(shè)計(jì) 3588次閱讀
下載排行
本周
- 1電子電路原理第七版PDF電子教材免費(fèi)下載
- 0.00 MB | 1491次下載 | 免費(fèi)
- 2單片機(jī)典型實(shí)例介紹
- 18.19 MB | 95次下載 | 1 積分
- 3S7-200PLC編程實(shí)例詳細(xì)資料
- 1.17 MB | 27次下載 | 1 積分
- 4筆記本電腦主板的元件識(shí)別和講解說(shuō)明
- 4.28 MB | 18次下載 | 4 積分
- 5開(kāi)關(guān)電源原理及各功能電路詳解
- 0.38 MB | 11次下載 | 免費(fèi)
- 6100W短波放大電路圖
- 0.05 MB | 4次下載 | 3 積分
- 7基于單片機(jī)和 SG3525的程控開(kāi)關(guān)電源設(shè)計(jì)
- 0.23 MB | 4次下載 | 免費(fèi)
- 8基于AT89C2051/4051單片機(jī)編程器的實(shí)驗(yàn)
- 0.11 MB | 4次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234313次下載 | 免費(fèi)
- 2PADS 9.0 2009最新版 -下載
- 0.00 MB | 66304次下載 | 免費(fèi)
- 3protel99下載protel99軟件下載(中文版)
- 0.00 MB | 51209次下載 | 免費(fèi)
- 4LabView 8.0 專業(yè)版下載 (3CD完整版)
- 0.00 MB | 51043次下載 | 免費(fèi)
- 5555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33562次下載 | 免費(fèi)
- 6接口電路圖大全
- 未知 | 30320次下載 | 免費(fèi)
- 7Multisim 10下載Multisim 10 中文版
- 0.00 MB | 28588次下載 | 免費(fèi)
- 8開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21539次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935053次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537793次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420026次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234313次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191183次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183277次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138039次下載 | 免費(fèi)
評(píng)論
查看更多