FIFO讀數取數

Sichg發表於2024-08-20

FIFO:先進先出的快取器。

常應用於頻寬不同或者跨時鐘域等資料傳輸情況。 相關引數:資料寬度,儲存深度,將空標誌位。空標誌位。將滿標誌位,滿標誌位。讀寫時鐘。其中將滿訊號與將空訊號相較於真正的滿訊號與空訊號都會提前一個時鐘週期拉高。

FIFO generator配置注意事項:

Basic選項卡:Interface Type 選 Native,即傳統介面。FIFO Implementation是指選擇想要實現的是同步FIFO還是非同步FIFO,以及使用什麼資源實現FIFO,當選擇Independent Clocks Block RAM,就是表示用塊RAM實現非同步FIFO。值得注意,FIFO是一種不包含地址的快取方式。因此這裡選擇RAM或者ROM其實不影響對FIFO的應用。 Native Ports選項卡:Read Mode用於設定讀FIFO時的讀模式,一般選預設的 Standard FIFO. 在Data Port Parameters中設定讀寫埠的資料匯流排寬度與FIFO深度(Write Width,Write Depth,Read Width)。Reset Pin是復位訊號,按需勾選。其餘預設。 Status Flags選項卡:按需勾選將滿和將空。其餘預設。 Data Counts選項卡:計數FIFO中有效資料的個數,為更方便觀察讀寫過程,可以將讀寫埠的計數都開啟。Write/Read Data Count表示計數值匯流排位寬。一般選8bit就夠用了。 Summary選項卡:顯示當前配置。確認當前配置無誤時直接點選OK. Generate Output Products視窗,直接點選Generate。

.veo例化模版:

fifo16to8 your_instance_name (
  .rst(rst),                      // input wire rst
  .wr_clk(wr_clk),                // input wire wr_clk
  .rd_clk(rd_clk),                // input wire rd_clk
  .din(din),                      // input wire [15 : 0] din
  .wr_en(wr_en),                  // input wire wr_en
  .rd_en(rd_en),                  // input wire rd_en
  .dout(dout),                    // output wire [7 : 0] dout
  .full(full),                    // output wire full
  .empty(empty),                  // output wire empty
  .rd_data_count(rd_data_count),  // output wire [10 : 0] rd_data_count
  .wr_rst_busy(wr_rst_busy),      // output wire wr_rst_busy
  .rd_rst_busy(rd_rst_busy)      // output wire rd_rst_busy
);

基礎的模組例化之fifo_rd:

功能:設定rd_cnt[7:0],以便取數存用。

`timescale 1ns / 1ns

  module fifo_rd(
      input             clk ,       // 時鐘訊號
      input             rst_n ,   // 復位訊號
      input                CLJwhole_en , //收好一組指令留待處理。
      output  reg  [7:0]  rd_cnt ,   // 向外讀64個。
      output  reg   fifo_rd_en        // FIFO讀使能
  );
  
 reg  [3:0]  state;
 
 //讀出FIFO的資料
 always @(posedge clk ) begin
     if(~rst_n) begin
         fifo_rd_en <= 1'b0;
         rd_cnt    <= 4'd0;
         state      <= 4'd0;
     end
     else begin
        case(state)
            2'd0: begin                     
                if(CLJwhole_en) begin        //如果檢測到FIFO被寫滿
                    rd_cnt <= 8'd1;     //給出第一個rd_cnt.
                    fifo_rd_en <= 1'b1; 
                    state <= 2'd1;         //開始取數。得到64個8位元數。
                end
                else
                    state <= state;
            end 
            2'd1: begin //接下來在rd_cnt從1數到64的過程中FIFO就會每個時鐘拍打出一個[7:0] dout。
                if(rd_cnt == 8'd65) begin //rd_cnt數到第65開始關閉rd_en。等待下一個whole_en。
                    fifo_rd_en <= 1'b0;    //關閉讀使能
                    rd_cnt <= 8'd0;
                    state   <= 2'd2;          //開始讀操作
                    end
                else
                    rd_cnt <= rd_cnt + 4'd1;
            end
            2'd2: begin
                rd_cnt <= 8'd0;
                fifo_rd_en <= 1'b0;    //關閉讀使能
                state      <= 4'd0;
            end 
            default : state <= 2'd0;
        endcase
     end
 end
 
 endmodule

fifo_rd功能最佳化之“存滿讀空預處理”

(留待編輯)

generate 變數i取數

wire [7:0]  rcvCLJ_fifo [63:0];
genvar i;
generate
for(i=0; i<=63; i=i+1) begin: data
   assign rcvCLJ_fifo[i] = (rd_cnt == i+2) ? fifo_dout : rcvCLJ_fifo[i];
end
endgenerate

為什麼從i+2開始算?

(留待編輯)

相關文章