加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

FPGA零基礎(chǔ)學(xué)習(xí)之Vivado-FIFO使用教程

2023/06/08
4797
閱讀需 15 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

作者:李西銳??校對:陸輝

大俠好,歡迎來到FPGA技術(shù)江湖。本系列將帶來FPGA的系統(tǒng)性學(xué)習(xí),從最基本的數(shù)字電路基礎(chǔ)開始,最詳細(xì)操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業(yè)學(xué)生、初入職場小白及打算進(jìn)階提升的職業(yè)開發(fā)者都可以有系統(tǒng)性學(xué)習(xí)的機(jī)會。

系統(tǒng)性的掌握技術(shù)開發(fā)以及相關(guān)要求,對個人就業(yè)以及職業(yè)發(fā)展都有著潛在的幫助,希望對大家有所幫助。本次帶來Vivado系列,F(xiàn)IFO使用教程。話不多說,上貨。

FIFO使用教程

FIFO的英文全稱叫做First in First out,即先進(jìn)先出。這也就決定了這個IP核的特殊性,先寫進(jìn)去的數(shù)據(jù)優(yōu)先被讀出,所以,F(xiàn)IFO是不需要地址信號線的,這也是它的一大特點(diǎn),通常用來做數(shù)據(jù)的緩存,或者用來解決高速異步數(shù)據(jù)的交互,即解決了跨時鐘域的問題。此外,F(xiàn)IFO還有一個特點(diǎn),就是數(shù)據(jù)被讀出之后就不存在了,不像RAM和ROM一樣,數(shù)據(jù)被讀出后還存在。所以我們?nèi)绻脒M(jìn)行多次的讀,那么就需要進(jìn)行同樣次數(shù)的寫。

FIFO分為同步時鐘和異步時鐘,同步FIFO指的是讀寫使用同一個時鐘,在時鐘沿信號來的時候進(jìn)行讀寫。異步FIFO是指讀寫在不同時鐘下進(jìn)行,這樣我們可以實(shí)現(xiàn)讀寫不同速度。

那么接下來,我們就來實(shí)現(xiàn)一下異步FIFO的讀寫過程。

上圖為選擇異步FIFO之后的圖示,在這個圖示中,我們給大家解釋一下每個信號的含義。

FIFO_WRITE:

full:FIFO的滿信號,當(dāng)FIFO的存儲空間寫滿了之后,此信號拉高,否則為低。此信號為FIFO的輸出信號

din[7:0]:FIFO的數(shù)據(jù)輸入,寫進(jìn)FIFO的數(shù)據(jù)通過此信號線進(jìn)入FIFO。

wr_en:FIFO的寫使能,當(dāng)我們要往FIFO里面寫入數(shù)據(jù)時,拉高此信號。此信號為FIFO的輸入。

FIFO_READ:

empty:FIFO的空信號,當(dāng)FIFO的存儲空間空了之后,此信號拉高,否則為低。此信號為FIFO的輸出信號。

dout:FIFO的數(shù)據(jù)輸出,讀出FIFO的數(shù)據(jù)通過此信號線輸出

rd_en:FIFO的讀使能,當(dāng)我們要從FIFO里面讀出數(shù)據(jù)時,拉高此信號。此信號為FIFO的輸出。

rst:FIFO復(fù)位,默認(rèn)高電平有效。

wr_clk:寫時鐘

rd_clk: 讀時鐘

wr_rst_busy:寫復(fù)位忙信號

rd_rst_busy:讀復(fù)位忙信號

在了解了FIFO的端口之后,我們來實(shí)現(xiàn)一個應(yīng)用實(shí)例。比如,我們以10MHz的速度往FIFO里面寫數(shù)據(jù),寫滿之后,在20MHz的時鐘下將數(shù)據(jù)讀出,一直讀空。當(dāng)然,在顯示應(yīng)用中,F(xiàn)IFO的讀寫是可以同步進(jìn)行的。

首先,我們先來新建工程。

新建好之后,我們先調(diào)用一下IP核:

在IP核管理器界面,搜索FIFO,然后選中圖示所選項(xiàng)雙擊打開。

在FIFO類型選項(xiàng),我們選擇異步FIFO。剛打開默認(rèn)的選項(xiàng)為同步FIFO。

在數(shù)據(jù)端口配置界面,我們將數(shù)據(jù)位寬改為8bit,深度使用1024。

復(fù)位端口在這就不再使用了,所以勾選位置取消掉。

在此界面出現(xiàn)了almost full flag和almost empty flag。這兩個信號是幾乎滿或空的標(biāo)志信號,在此實(shí)驗(yàn)中,我們不使用。

Data?count是FIFO數(shù)據(jù)用量計(jì)數(shù)器,代表了此時FIFO的內(nèi)部存儲被使用的情況。假設(shè)我們寫進(jìn)去了10個數(shù),那么兩個計(jì)數(shù)器都為10。

此界面為IP核的信息,在此界面可以看出,我們的讀寫深度發(fā)生了變化,我們在前面設(shè)置的深度為1024,但是在此處顯示的卻是1023。原因是因?yàn)镕IFO結(jié)構(gòu)的特殊性,并不是我們設(shè)置的有問題。所以,在我們這個異步FIFO中,深度為1023。

點(diǎn)擊OK直接生成。在點(diǎn)擊Generate。

此外,我們還需要兩個不同時鐘,在這里我們使用鎖相環(huán)生成。

在管理界面搜索clock。配置過程我們在此前已經(jīng)講過,就不在過多敘述。

接下來我們寫一下fifo的寫控制器,代碼如下:

1   module fifo_wr(2     3     input   wire             clk,4     input   wire             rst_n,5     input   wire             empty,6     input   wire             full,7     output   reg             fifo_wr_en,8     output   reg     [7:0]      fifo_data_in9   );1011    reg         state;12    13    always @ (posedge clk, negedge rst_n)14    begin15      if(rst_n == 1'b0)16        begin17          fifo_wr_en <= 1'b0;18          fifo_data_in <= 8'd0;19          state <= 1'b0;20        end21      else22        case(state)23          1'b0  :  begin24                  if(empty)25                    state <= 1'b1;26                  else27                    state <= 1'b0;28                end29          1'b1  :  begin30                  if(full)31                    begin32                      fifo_wr_en <= 1'b0;33                      fifo_data_in <= 8'd0;34                      state <= 1'b0;35                    end36                  else37                    begin38                      fifo_wr_en <= 1'b1;39                      fifo_data_in <= fifo_data_in + 1'b1;40                      state <= 1'b1;41                    end42                end43        endcase44    end4546  endmodule

因?yàn)槲覀兊膶?shí)驗(yàn)是讀空了才寫,所以我們用狀態(tài)機(jī)來做,先判斷FIFO是否為空。讀控制器代碼如下:

1   module fifo_rd(2     3     input   wire               clk,4     input   wire               rst_n,5     input   wire               empty,6     input   wire               full,7     output   reg               fifo_rd_en8   );9 10    reg         state;11    12    always @ (posedge clk, negedge rst_n)13    begin14      if(rst_n == 1'b0)15        begin16          fifo_rd_en <= 1'b0;17          state <= 1'b0;18        end19      else20        case(state)21          1'b0  :  begin22                  if(full)23                    state <= 1'b1;24                  else25                    state <= 1'b0;26                end27          1'b1  :  begin28                  if(empty)29                    begin30                      fifo_rd_en <= 1'b0;31                      state <= 1'b0;32                    end33                  else34                    begin35                      fifo_rd_en <= 1'b1;36                      state <= 1'b1;37                    end38                end39        endcase40    end4142  endmodule

頂層代碼如下:

1   module fifo(2     3     input   wire               clk,4     input   wire               rst_n,5     output   wire       [7:0]      q6   );7     8     wire           fifo_wr_clk;9     wire           fifo_rd_clk;10    wire           locked;11    wire           empty;12    wire           full;13    wire           fifo_wr_en;14    wire     [7:0]    fifo_data_in;15    wire           fifo_rd_en;16    17    clk_wiz_0 clk_wiz_0_inst18     (19    // Clock out ports20    .clk_out1(fifo_wr_clk),     // output clk_out121    .clk_out2(fifo_rd_clk),     // output clk_out222    // Status and control signals23    .reset(~rst_n), // input reset24    .locked(locked),       // output locked25     // Clock in ports26    .clk_in1(clk));      // input clk_in127    28    fifo_wr fifo_wr_inst(29    30    .clk            (fifo_wr_clk),31    .rst_n            (locked  ),32    .empty            (empty    ),33    .full            (full    ),34    .fifo_wr_en          (fifo_wr_en  ),35    .fifo_data_in        (fifo_data_in)36  );3738    fifo_generator_0 fifo_generator_0_inst (39      .wr_clk(fifo_wr_clk),  // input wire wr_clk40      .rd_clk(fifo_rd_clk),  // input wire rd_clk41      .din(fifo_data_in),        // input wire [7 : 0] din42      .wr_en(fifo_wr_en),    // input wire wr_en43      .rd_en(fifo_rd_en),    // input wire rd_en44      .dout(q),      // output wire [7 : 0] dout45      .full(full),      // output wire full46      .empty(empty)    // output wire empty47    );4849    fifo_rd fifo_rd_inst(50    51    .clk        (fifo_rd_clk),52    .rst_n        (locked    ),53    .empty        (empty    ),54    .full        (full    ),55    .fifo_rd_en      (fifo_rd_en)56  );57    58  endmodule

代碼寫完之后,我們寫個仿真驗(yàn)證一下波形,代碼如下:

1   `timescale 1ns / 1ps2 3   module fifo_tb;4 5     reg                clk;6     reg                rst_n;7     wire       [7:0]      q;8     9     initial begin10      clk = 0;11      rst_n = 0;12      #105;13      rst_n = 1;14      #10000;15      $stop;16    end17    18    always #10 clk = ~clk;19    20    fifo fifo_inst(21    22    .clk      (clk),23    .rst_n      (rst_n),24    .q        (q)25  );2627  endmodule

打開波形之后,我們將讀寫控制模塊的信號全部添加到波形窗口:

添加好之后,點(diǎn)擊restart和run-all

由于波形默認(rèn)運(yùn)行10us,我們觀察不到全部波形,所以,在此我們繼續(xù)點(diǎn)擊run-all,然后點(diǎn)擊break,讓仿真停止。

然后,我們觀察波形:

在波形里面可以清楚的看到我們的fifo_data_in和q的波形,一長一短。這是因?yàn)樽x的速度快,所以波形維持的時間短。寫數(shù)據(jù)的時間長度是讀數(shù)據(jù)時間長度的兩倍。

然后放大波形觀察其他信號:

在黃色光標(biāo)位置,可以看到滿信號拉高了,然后寫使能就拉低了,狀態(tài)開始進(jìn)入到讀。在讀使能拉高之后,輸出q就有了數(shù)據(jù),但是我們的empty信號維持了一段時間才拉低,這是因?yàn)閒ifo的特殊結(jié)構(gòu)導(dǎo)致的,在此我們就不再過多討論。

結(jié)論:異步FIFO控制正確,仿真波形輸入和輸出信號正常。

 

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級 參考價(jià)格 更多信息
5M240ZT144C5N 1 Altera Corporation Flash PLD, 17.7ns, 192-Cell, CMOS, PQFP144, 22 X 22 MM, 0.50 MM PITCH, LEAD FREE, TQFP-144

ECAD模型

下載ECAD模型
$4.9 查看
10M50DAF256I7G 1 Intel Corporation Field Programmable Gate Array, 50000-Cell, CMOS, PBGA256, 17 X 17 MM, 1 MM PITCH, ROHS COMPLIANT, FBGA-256

ECAD模型

下載ECAD模型
$166.08 查看
A3P250-FG144 1 Microsemi FPGA & SoC Field Programmable Gate Array, 250000 Gates, CMOS, PBGA144, 1 MM PITCH, FBGA-144
$21.67 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

任何技術(shù)的學(xué)習(xí)就好比一個江湖,對于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。