[文檔].艾米電子 – FIFO緩衝,Verilog

來源:互聯網
上載者:User
文章目錄
  • 基於迴圈隊列的實現
對讀者的假設

已經掌握:

  • 可程式化邏輯基礎
  • Verilog HDL基礎
  • 使用Verilog設計的Quartus II入門指南
  • 使用Verilog設計的ModelSIm入門指南
內容

FIFO緩衝是介於兩個子系統之間的彈性儲存空間,其概念圖1所示。它有兩個控制訊號,wr和rd,用於讀操作和寫操作。當wr被插入時,輸入的資料被寫入緩衝,此時讀操作被忽視。FIFO緩衝的head一般情況下總是有效,因此可在任意時間被讀取。rd訊號實際上就像“remove”訊號;當其被插入的時候,FIFO緩衝的第一個項(即head)被移除,下一個項變為可用項。

 

圖1 FIFO緩衝的概念框圖

在許多應用中,FIFO緩衝是一種臨界組件,其實現的最佳化相當複雜。在本節中,我們介紹一種簡單的、真實的基於迴圈序列設計的FIFO緩衝。更有效、基於指定器件實現的FIFO緩衝可在Altera或Xilinx的相關手冊中找到。

基於迴圈隊列的實現

一種實現FIFO緩衝的方法是給寄存器檔案添加一個控制電路。寄存器檔案通過兩個指標像迴圈隊列一樣來排列寄存器。寫指標(write poniter)指向隊列的頭(head);讀指標(read poniter)指向隊列的尾(tail)。每次讀操作或寫操作,指標都會前進一個位置。8-字迴圈隊列的操作2所示。

圖2 基於迴圈隊列的FIFO緩衝

FIFO緩衝通常包括兩個標誌訊號,full和empty,相應地來指示FIFO滿(即不可寫)或FIFO空(即不可讀)。這兩種情況發生在讀指標和寫指標相等的時候,2(a)、(f)和(i)所示的情況。控制器最難的設計任務是擷取一種分辨這兩種情形的機制。一種方案是使用觸發器來跟蹤empty和full標誌。當系統被初始化時,觸發器被設定為1和0;然後在每一個刻度根據wr和rd的值來修改。

代碼 FIFO緩衝

module fifo#(  parameter B=8, // number of bits in a word            W=3  // number of address bits)(  // global clock and aysn reset  input clk,   input rst_n,  // fifo interface  //  fifo control signnal  input rd,   input wr,  //  fifo status signal  output empty,   output full,  // fifo data bus  input [B-1:0] w_data,  output [B-1:0] r_data);// signal declarationreg [B-1:0] array_reg [2**W-1:0];  // register arrayreg [W-1:0] w_ptr_reg, w_ptr_next, w_ptr_succ;reg [W-1:0] r_ptr_reg, r_ptr_next, r_ptr_succ;reg full_reg, empty_reg, full_next, empty_next;wire wr_en;// body// register file write operationalways @(posedge clk)  if (wr_en)    array_reg[w_ptr_reg] <= w_data;// register file read operationassign r_data = array_reg[r_ptr_reg];// write enabled only when FIFO is not fullassign wr_en = wr & ~full_reg;// fifo control logic// register for read and write pointersalways @(posedge clk, negedge rst_n)  if (!rst_n)  begin    w_ptr_reg <= 0;    r_ptr_reg <= 0;    full_reg <= 1'b0;    empty_reg <= 1'b1;  end  else  begin    w_ptr_reg <= w_ptr_next;    r_ptr_reg <= r_ptr_next;    full_reg <= full_next;    empty_reg <= empty_next;  end// next-state logic for read and write pointersalways @*begin  // successive pointer values  w_ptr_succ = w_ptr_reg + 1;  r_ptr_succ = r_ptr_reg + 1;  // default: keep old values  w_ptr_next = w_ptr_reg;  r_ptr_next = r_ptr_reg;  full_next = full_reg;  empty_next = empty_reg;  case ({wr, rd})    // 2'b00:  no op    2'b01: // read      if (~empty_reg) // not empty      begin        r_ptr_next = r_ptr_succ;        full_next = 1'b0;        if (r_ptr_succ==w_ptr_reg)          empty_next = 1'b1;      end    2'b10: // write    if (~full_reg) // not full    begin      w_ptr_next = w_ptr_succ;      empty_next = 1'b0;      if (w_ptr_succ==r_ptr_reg)        full_next = 1'b1;    end    2'b11: // write and read    begin      w_ptr_next = w_ptr_succ;      r_ptr_next = r_ptr_succ;    end  endcaseend// outputassign full = full_reg;assign empty = empty_reg;endmodule

代碼被分為寄存器檔案和FIFO控制器兩部分。控制器由兩個指標和兩個標誌觸發器組成,它們的次態邏輯會檢測wr和rd訊號,以採取相應的動作。舉例說,在“10”條件下,即暗示只發生寫操作。先檢查標誌觸發器,以確保緩衝不為滿。如果滿足條件,我們將寫指標前進一位,並清除空標誌。再多儲存一個字(位移地址為1所對應的資料)可能使得FIFO緩衝滿,即新的寫指標趕上了讀指標,我們使用w_ptr_succ==r_ptr_reg運算式來描述這一情況。

根據圖2,我寫了下面的testbench,其RTL模擬結果與圖2一致。

代碼 FIFO緩衝的testbench

`timescale 1ns/1nsmodule fifo_tb;localparam T=20; // clock period// global clock and asyn resetreg clk, rst_n;// fifo interfacereg rd, wr;wire empty, full;reg [7:0] w_data;wire [7:0] r_data;// fifo instantiationfifo #(.B(8), .W(3)) fifo_inst(  .clk(clk), .rst_n(rst_n),  .rd(rd), .wr(wr),  .empty(empty), .full(full),  .w_data(w_data), .r_data(r_data));// clcokalwaysbegin  clk = 1'b0;   #(T/2);  clk = 1'b1;  #(T/2);end// resetinitialbegin  rst_n = 1'b0;  #(T/2)  rst_n = 1'b1;end// stimulus bodyinitial begin  // initial input; empty  rd=0; wr=0; w_data=8'h00;  @(posedge rst_n); // wait to deassert rst_n  @(negedge clk); // wait for a clock  // 1 write  wr=1; w_data=8'h11;  @(negedge clk); // wait to assert wr  wr=0;  @(negedge clk); // wait to deassert wr  // 3 writes  wr=1;  repeat(3)  begin    w_data=w_data+8'h11;    @(negedge clk);   end  wr=0;  @(negedge clk);  // 1 read  rd=1;  @(negedge clk); // wait to assert rd  rd=0;  @(negedge clk) // wait to deassert rd  // 4 writes  wr=1;  repeat(4)  begin    w_data=w_data+8'h11;    @(negedge clk);  end  wr=0;  @(negedge clk);   // 1 write; full  wr=1; w_data=8'hAA;  @(negedge clk);   wr=0;  @(negedge clk);  // 2 reads  rd=1;  repeat(2) @(negedge clk);  rd=0;   @(negedge clk);  // 5 reads  rd=1;  repeat(5) @(negedge clk);  rd=0;  @(negedge clk);  // 1 read; empty  rd=1;  @(negedge clk);  rd=0;  @(negedge clk);  $stop;endendmodule

圖3 RTL級模擬波形

參考

1 Pong P. Chu.FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version.Wiley

另見

[與艾米一起學FPGA/SOPC].[邏輯實驗文檔連載計劃]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.