亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

同步FIFO設(shè)計(jì)詳解及代碼分享 環(huán)球時(shí)快訊

2023-06-27 10:11:05 來源:FPGA探索者

1. FIFO 簡介

FIFO (先入先出, First In First Out )存儲(chǔ)器,在 FPGA和數(shù)字 IC設(shè)計(jì)中非常常用。 根據(jù)接入的時(shí)鐘信號(hào),可以分為同步 FIFO 和異步 FIFO 。

**FIFO 底層基于雙口 RAM** ,同步 FIFO 的讀寫時(shí)鐘一致,異步 FIFO 讀時(shí)鐘和寫時(shí)鐘不同。 同步時(shí)鐘主要應(yīng)用于速率匹配(數(shù)據(jù)緩沖),類似于乒乓存儲(chǔ)提高性能的思想,可以讓后級(jí)不必等待前級(jí)過多時(shí)間; 異步 FIFO 主要用于多 bit 信號(hào)的跨時(shí)鐘域處理。

本文討論同步 FIFO 的結(jié)構(gòu)及控制邏輯設(shè)計(jì),并給出代碼。


(相關(guān)資料圖)

2. 同步 FIFO 接口

對(duì)于同步 FIFO ,包含必要的接口如下圖所示:

(1) clk : 時(shí)鐘信號(hào),讀寫共用;

(2) rst_n : 復(fù)位信號(hào),視具體設(shè)計(jì)和芯片采用同步復(fù)位還是異步復(fù)位,此處默認(rèn)使用異步低電平復(fù)位;

(3) wdata : 寫數(shù)據(jù)信號(hào),信號(hào)后帶“ \\ ”表示是多 bit 信號(hào);

(4) rdata : 讀數(shù)據(jù)信號(hào),信號(hào)后帶“ \\ ”表示是多 bit 信號(hào);

(5) wfull : 滿信號(hào),指示 FIFO 寫滿了,不能再寫了,如果再寫會(huì)覆蓋掉還沒讀出的寫入數(shù)據(jù),造成數(shù)據(jù)丟失;

(6) rempty : 空信號(hào),指示 FIFO 讀空了,不能在讀了,如果再讀相當(dāng)于有的數(shù)據(jù)重復(fù)讀了第二遍,造成數(shù)據(jù)錯(cuò)誤;

(7) winc : 寫使能信號(hào),寫使能有效時(shí)表示希望能寫入數(shù)據(jù);

(8) rinc : 讀使能信號(hào),讀使能有效時(shí)表示希望能讀出數(shù)據(jù);

3. 雙口 RAM 接口

在實(shí)現(xiàn) FIFO 時(shí),無論是同步 FIFO 還是異步 FIFO ,通常會(huì)通過雙口 RAM ( Dual Port RAM )并添加一些必要的邏輯來實(shí)現(xiàn)。雙口 RAM 的接口如下圖所示。

**左側(cè)全部是寫時(shí)鐘域的,包括寫時(shí)鐘、寫數(shù)據(jù)、寫地址和寫使能信號(hào);

**

右側(cè)全部是讀時(shí)鐘域的,包括讀時(shí)鐘、讀數(shù)據(jù)、讀地址和讀使能信號(hào);

4. 基于雙口 RAM 的同步 FIFO 結(jié)構(gòu)

根據(jù)同步 FIFO 的接口和雙口 RAM 的接口,在借助雙口 RAM 實(shí)現(xiàn)同步 FIFO 時(shí),如下圖所示結(jié)構(gòu),只需要加入讀、寫控制邏輯即可。在寫邏輯中,用于產(chǎn)生寫地址和寫滿信號(hào); 在讀邏輯中,用于產(chǎn)生讀地址和讀空信號(hào)。 讀寫控制邏輯還需要受到讀寫使能信號(hào)的控制。

5. 讀寫地址產(chǎn)生邏輯

讀寫地址什么時(shí)候能夠遞增?

顯然,對(duì)于寫地址必須滿足:

(1) 寫使能有效(要寫入);

(2) 沒寫滿(能寫入);

即:

always @ (posedge clk ornegedge rst_n) begin  if(~rst_n) begin    waddr <= "b0;  end   else begin    if( winc && ~wfull ) begin      waddr <= waddr + 1"b1;    end     else begin      waddr <= waddr;        end   end end

對(duì)于讀地址必須滿足:

(1) 讀使能有效(要讀出);

(2) 沒讀空(能讀出);

即:

always @ (posedge clk or negedge rst_n) begin  if(~rst_n) begin    raddr<= "b0;  end   else begin    if( rinc && ~rempty ) begin      raddr <= raddr + 1"b1;    end     else begin      raddr <= raddr;        end   end end

6. 空滿信號(hào)產(chǎn)生邏輯

搞定了讀寫地址的控制邏輯,還差最后一步也是最關(guān)鍵的信號(hào):空滿信號(hào)如何產(chǎn)生。

空: 讀空,讀地址追上寫地址;

滿: 寫滿,寫地址追上讀地址。

問題來了: 怎么判地址斷追上了呢? 如果地址相等那應(yīng)該是追上了,即 raadr == waddr 或者 wddr == raddr 。 如果按照這種判斷,顯然這兩個(gè)地址追上對(duì)方的判斷是等效的,無法區(qū)分出來到底是寫追上讀還是讀追上寫。

可以考慮: 使用 1 個(gè)標(biāo)志位 flag 來額外指示寫追上讀還是讀追上寫。

參考前人的文獻(xiàn),判斷空滿的方式有多種,非常常用的一種是 Clifford E. Cummings 文章中提到的 擴(kuò)展 1 bit 的讀寫地址方法,也就是說,將前面提到的 flag 指示信號(hào)和原本 N 位的讀寫地址結(jié)合,使用 N+1 位的讀寫地址,其中最高位用于判斷空滿信號(hào),其余低位還是正常用于讀寫地址索引。

以一個(gè) 4 深度的 FIFO 實(shí)例來說明, 4 深度原本需要 2 bit 的讀寫地址,現(xiàn)在擴(kuò)展成 3 bit 。

使用低 2 位來進(jìn)行雙口 RAM 的地址索引,高位用于判斷空滿。 對(duì)于空信號(hào),可以知道當(dāng) FIFO 里沒有待讀出的數(shù)據(jù)時(shí)產(chǎn)生。** 也就是說,此時(shí)讀追上了寫,把之前寫的數(shù)據(jù)剛剛?cè)慷汲?,讀地址和寫地址此時(shí)指向相同的位置,讀地址 - 寫地址 =0** ,即

raddr == waddr

對(duì)于寫滿信號(hào), **當(dāng)寫入后還沒被讀出的數(shù)據(jù)恰好是 FIFO 深度的時(shí)候,產(chǎn)生滿信號(hào),即寫地址 - 讀地址 = FIFO 深度 = 4 ** 。 對(duì)照下圖可以發(fā)現(xiàn),此時(shí)對(duì)于雙口 RAM 的 2 bit 的地址來說,讀寫地址一致; 對(duì)于最高位來所,寫是 1 而讀是 0 。

再考慮下圖所示的一種情況,寫入待讀出的數(shù)據(jù)仍然是 4 個(gè),此時(shí)也是 4 深度的 FIFO 已經(jīng)滿了。 讀寫地址的低位相同,高位是寫 0 讀 1 。

對(duì)于寫滿的 2 種情況,總結(jié)下來,都是低位相同,最高位相反。

即:

raddr[N] = = ~waddr[N]    raddr[N-1:0] = = waddr[N-1:0]

也就是:

raddr == {~waddr[N], waddr[N-1:0]}

所以,空滿邏輯產(chǎn)生的代碼為:

always @ (posedge clk or negedge rst_n) begin  if(~rst_n) begin    wfull <= "b0;    rempty <= "b0;  end   else begin    wfull <= (raddr == {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH-1:0]});    rempty <= (raddr == waddr);  end end

7. 全部代碼

`timescale 1ns/1ns  /****************************/// 作者:FPGA探索者/****************************/module sfifo#(  parameter  WIDTH = 8,  parameter   DEPTH = 16)(  input           clk    ,   input           rst_n  ,  input           winc  ,  input            rinc  ,  input     [WIDTH-1:0]  wdata  ,  output reg        wfull  ,  output reg        rempty  ,  output wire [WIDTH-1:0]  rdata);  // 用localparam定義一個(gè)參數(shù),可以在文件內(nèi)使用    localparam ADDR_WIDTH = $clog2(DEPTH);    reg [ADDR_WIDTH:0] waddr;    reg [ADDR_WIDTH:0] raddr;    always @ (posedge clk or negedge rst_n) begin        if(~rst_n) begin            waddr <= "b0;        end         else begin            if( winc && ~wfull ) begin                waddr <= waddr + 1"b1;            end             else begin                waddr <= waddr;                end         end     end     always @ (posedge clk or negedge rst_n) begin        if(~rst_n) begin            raddr <= "b0;        end         else begin            if( rinc && ~rempty ) begin                raddr <= raddr + 1"b1;            end             else begin                raddr <= raddr;                end         end     end     always @ (posedge clk or negedge rst_n) begin        if(~rst_n) begin            wfull <= "b0;            rempty <= "b0;        end         else begin            wfull <= (raddr == {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH-1:0]});            rempty <= (raddr == waddr);        end     end // 帶有 parameter 參數(shù)的例化格式    dual_port_RAM      #(        .DEPTH(DEPTH),        .WIDTH(WIDTH)    )    dual_port_RAM_U0     (        .wclk(clk),      .wenc(winc),        .waddr(waddr[ADDR_WIDTH-1:0]),       .wdata(wdata),              .rclk(clk),        .renc(rinc),        .raddr(raddr[ADDR_WIDTH-1:0]),       .rdata(rdata)     );       endmodule/**************RAM 子模塊*************/module dual_port_RAM #(parameter DEPTH = 16,             parameter WIDTH = 8)(   input wclk  ,input wenc  ,input [$clog2(DEPTH)-1:0] waddr  //深度對(duì)2取對(duì)數(shù),得到地址的位寬。  ,input [WIDTH-1:0] wdata        //數(shù)據(jù)寫入  ,input rclk  ,input renc  ,input [$clog2(DEPTH)-1:0] raddr  //深度對(duì)2取對(duì)數(shù),得到地址的位寬。  ,output reg [WIDTH-1:0] rdata     //數(shù)據(jù)輸出);reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];always @(posedge wclk) begin  if(wenc)    RAM_MEM[waddr] <= wdata;end always @(posedge rclk) begin  if(renc)    rdata <= RAM_MEM[raddr];end endmodule

標(biāo)簽:

上一篇:焦點(diǎn)速看:自動(dòng)駕駛汽車避障、路徑規(guī)劃和控制技術(shù)詳解
下一篇:最后一頁