0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA的異步FIFO設(shè)計(jì)架構(gòu)

SwM2_ChinaAET ? 來(lái)源:未知 ? 作者:李倩 ? 2018-09-25 14:34 ? 次閱讀

今天要介紹的異步FIFO,可以有不同的讀寫(xiě)時(shí)鐘,即不同的時(shí)鐘域。由于異步FIFO沒(méi)有外部地址端口,因此內(nèi)部采用讀寫(xiě)指針并順序讀寫(xiě),即先寫(xiě)進(jìn)FIFO的數(shù)據(jù)先讀?。ê?jiǎn)稱(chēng)先進(jìn)先出)。這里的讀寫(xiě)指針是異步的,處理不同的時(shí)鐘域,而異步FIFO的空滿(mǎn)標(biāo)志位是根據(jù)讀寫(xiě)指針的情況得到的。

為了得到正確的空滿(mǎn)標(biāo)志位,需要對(duì)讀寫(xiě)指針進(jìn)行同步。一般情況下,如果一個(gè)時(shí)鐘域的信號(hào)直接給另一個(gè)時(shí)鐘域采集,可能會(huì)產(chǎn)生亞穩(wěn)態(tài),亞穩(wěn)態(tài)的產(chǎn)生對(duì)設(shè)計(jì)而言是致命的。為了減少不同時(shí)鐘域間的亞穩(wěn)態(tài)問(wèn)題,我們先對(duì)它進(jìn)行兩拍寄存同步,如圖1所示。

當(dāng)然,對(duì)異步信號(hào)的寄存越多,產(chǎn)生亞穩(wěn)態(tài)的概率就越小,但延時(shí)越多。不過(guò)一般情況下,寄存兩拍就夠了。為了繼續(xù)減少亞穩(wěn)態(tài)產(chǎn)生的概率,在對(duì)異步信號(hào)同步之前,將其轉(zhuǎn)換為格雷碼,使其每個(gè)狀態(tài)只有一個(gè)位在變化。例如,假設(shè)N位二進(jìn)制變量產(chǎn)生的亞穩(wěn)態(tài)概率為a,那么二進(jìn)制轉(zhuǎn)換成格雷碼后其產(chǎn)生的亞穩(wěn)態(tài)概率則為a/N。

圖1 對(duì)異步信號(hào)用兩級(jí)寄存器同步

根據(jù)上述原理,設(shè)計(jì)了異步FIFO的架構(gòu),如圖2所示。

圖2 異步FIFO設(shè)計(jì)架構(gòu)

根據(jù)異步FIFO的設(shè)計(jì)架構(gòu),歸納以下設(shè)計(jì)步驟:

寫(xiě)時(shí)鐘域:

(1)根據(jù)寫(xiě)使能wr_en和寫(xiě)滿(mǎn)標(biāo)志位wr_full產(chǎn)生二進(jìn)制寫(xiě)指針

(2)根據(jù)二進(jìn)制寫(xiě)指針產(chǎn)生雙端口RAM的寫(xiě)地址

(3)由二進(jìn)制寫(xiě)指針轉(zhuǎn)換成格雷碼寫(xiě)指針

(4)對(duì)格雷碼讀指針在寫(xiě)時(shí)鐘域中進(jìn)行兩級(jí)同步得同步后格雷碼讀指針

(5)同步后格雷碼讀指針轉(zhuǎn)化成同步后二進(jìn)制讀指針

(6)步驟(3)與步驟(4)比較得寫(xiě)滿(mǎn)標(biāo)志位wr_full

(7)步驟(1)與步驟(5)相減得指示寫(xiě)FIFO的數(shù)據(jù)量

讀時(shí)鐘域:

(8)根據(jù)讀使能rd_en和讀空標(biāo)志位rd_empty產(chǎn)生二進(jìn)制讀指針

(9)根據(jù)二進(jìn)制讀指針產(chǎn)生雙端口RAM的讀地址

(10)由二進(jìn)制讀指針轉(zhuǎn)換成格雷碼讀指針

(11)對(duì)格雷碼寫(xiě)指針在讀時(shí)鐘域中進(jìn)行兩級(jí)同步得同步后格雷碼寫(xiě)指針

(12)同步后格雷碼寫(xiě)指針轉(zhuǎn)化成同步后二進(jìn)制寫(xiě)指針

(13)步驟(10)與步驟(11)比較得讀空標(biāo)志位rd_empty

(14)步驟(8)與步驟(12)相減得指示讀FIFO的數(shù)據(jù)量

Verilog HDL設(shè)計(jì)電路,如下所示:

**------------------------------文件信息--------------------------------

** 文件名: asyn_fifo.v

** 創(chuàng)建者: CrazyBird

** 創(chuàng)建日期: 2016-1-16

** 版本號(hào): v1.0

** 功能描述: 異步FIFO,用于處理不同的時(shí)鐘域

**

***********************************************************************/

// synopsys translate_off

`timescale 1 ns / 1 ps

// synopsys translate_on

module asyn_fifo(

wr_rst_n,

wr_clk,

wr_en,

wr_data,

wr_full,

wr_cnt,

rd_rst_n,

rd_clk,

rd_en,

rd_data,

rd_empty,

rd_cnt

);

//******************************************************************

// 參數(shù)定義

//******************************************************************

parameter C_DATA_WIDTH = 8;

parameter C_FIFO_DEPTH_WIDTH = 4;

//******************************************************************

// 端口定義

//******************************************************************

input wr_rst_n;

input wr_clk;

input wr_en;

input [C_DATA_WIDTH-1:0] wr_data;

output reg wr_full;

output reg [C_FIFO_DEPTH_WIDTH:0] wr_cnt;

input rd_rst_n;

input rd_clk;

input rd_en;

output [C_DATA_WIDTH-1:0] rd_data;

output reg rd_empty;

output reg [C_FIFO_DEPTH_WIDTH:0] rd_cnt;

//******************************************************************

// 內(nèi)部變量定義

//******************************************************************

reg [C_DATA_WIDTH-1:0] mem [0:(1 《《 C_FIFO_DEPTH_WIDTH)-1];

wire [C_FIFO_DEPTH_WIDTH-1:0] wr_addr;

wire [C_FIFO_DEPTH_WIDTH-1:0] rd_addr;

wire [C_FIFO_DEPTH_WIDTH:0] next_wr_bin_ptr;

wire [C_FIFO_DEPTH_WIDTH:0] next_rd_bin_ptr;

reg [C_FIFO_DEPTH_WIDTH:0] wr_bin_ptr;

reg [C_FIFO_DEPTH_WIDTH:0] rd_bin_ptr;

wire [C_FIFO_DEPTH_WIDTH:0] next_wr_gray_ptr;

wire [C_FIFO_DEPTH_WIDTH:0] next_rd_gray_ptr;

wire [C_FIFO_DEPTH_WIDTH:0] syn_wr_bin_ptr_rd_clk;

wire [C_FIFO_DEPTH_WIDTH:0] syn_rd_bin_ptr_wr_clk;

wire [C_FIFO_DEPTH_WIDTH:0] syn_wr_gray_ptr_rd_clk;

wire [C_FIFO_DEPTH_WIDTH:0] syn_rd_gray_ptr_wr_clk;

wire [C_FIFO_DEPTH_WIDTH:0] wr_cnt_w;

wire [C_FIFO_DEPTH_WIDTH:0] rd_cnt_w;

wire wr_full_w;

wire rd_empty_w;

//******************************************************************

// 雙端口RAM的讀寫(xiě)

//******************************************************************

// 寫(xiě)RAM

always @(posedge wr_clk)

begin

if((wr_en & ~wr_full) == 1‘b1)

mem[wr_addr] 《= wr_data;

end

// 讀RAM

assign rd_data = mem[rd_addr];

//******************************************************************

// 二進(jìn)制寫(xiě)指針的產(chǎn)生

//******************************************************************

assign next_wr_bin_ptr = wr_bin_ptr + (wr_en & ~wr_full);

always @(posedge wr_clk or negedge wr_rst_n)

begin

if(wr_rst_n == 1’b0)

wr_bin_ptr 《= {(C_FIFO_DEPTH_WIDTH+1){1‘b0}};

else

wr_bin_ptr 《= next_wr_bin_ptr;

end

//******************************************************************

// RAM寫(xiě)地址的產(chǎn)生

//******************************************************************

assign wr_addr = wr_bin_ptr[C_FIFO_DEPTH_WIDTH-1:0];

//******************************************************************

// 二進(jìn)制寫(xiě)指針轉(zhuǎn)換成格雷碼寫(xiě)指針

//******************************************************************

bin2gray #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_bin2gray_wr (

.bin ( next_wr_bin_ptr ),

.gray ( next_wr_gray_ptr )

);

//******************************************************************

// 對(duì)格雷碼讀指針在寫(xiě)時(shí)鐘域中進(jìn)行兩級(jí)同步

//******************************************************************

double_syn_ff #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_double_syn_ff_wr (

.rst_n ( wr_rst_n ),

.clk ( wr_clk ),

.din ( next_rd_gray_ptr ),

.dout ( syn_rd_gray_ptr_wr_clk )

);

//******************************************************************

// 同步后的格雷碼讀指針轉(zhuǎn)換成同步后的二進(jìn)制讀指針

//******************************************************************

gray2bin #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_gray2bin_wr (

.gray ( syn_rd_gray_ptr_wr_clk ),

.bin ( syn_rd_bin_ptr_wr_clk )

);

//******************************************************************

// FIFO寫(xiě)滿(mǎn)標(biāo)志位的產(chǎn)生和寫(xiě)FIFO數(shù)據(jù)量的計(jì)數(shù)

//******************************************************************

assign wr_full_w = (next_wr_gray_ptr == ({~syn_rd_gray_ptr_wr_clk[C_FIFO_DEPTH_WIDTH:C_FIFO_DEPTH_WIDTH-1],

syn_rd_gray_ptr_wr_clk[C_FIFO_DEPTH_WIDTH-2:0]}));

assign wr_cnt_w = next_wr_bin_ptr - syn_rd_bin_ptr_wr_clk;

always @(posedge wr_clk or negedge wr_rst_n)

begin

if(wr_rst_n == 1’b0)

begin

wr_full 《= 1‘b0;

wr_cnt 《= {(C_FIFO_DEPTH_WIDTH+1){1’b0}};

end

else

begin

wr_full 《= wr_full_w;

wr_cnt 《= wr_cnt_w;

end

end

//******************************************************************

// 二進(jìn)制讀指針的產(chǎn)生

//******************************************************************

assign next_rd_bin_ptr = rd_bin_ptr + (rd_en & ~rd_empty);

always @(posedge rd_clk or negedge rd_rst_n)

begin

if(rd_rst_n == 1‘b0)

rd_bin_ptr 《= {(C_FIFO_DEPTH_WIDTH+1){1’b0}};

else

rd_bin_ptr 《= next_rd_bin_ptr;

end

//******************************************************************

// RAM讀地址的產(chǎn)生

//******************************************************************

assign rd_addr = rd_bin_ptr[C_FIFO_DEPTH_WIDTH-1:0];

//******************************************************************

// 二進(jìn)制讀指針轉(zhuǎn)換成格雷碼讀指針

//******************************************************************

bin2gray #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_bin2gray_rd (

.bin ( next_rd_bin_ptr ),

.gray ( next_rd_gray_ptr )

);

//******************************************************************

// 對(duì)格雷碼寫(xiě)指針在讀時(shí)鐘域中進(jìn)行兩級(jí)同步

//******************************************************************

double_syn_ff #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_double_syn_ff_rd (

.rst_n ( rd_rst_n ),

.clk ( rd_clk ),

.din ( next_wr_gray_ptr ),

.dout ( syn_wr_gray_ptr_rd_clk )

);

//******************************************************************

// 同步后的格雷碼寫(xiě)指針轉(zhuǎn)換成同步后的二進(jìn)制寫(xiě)指針

//******************************************************************

gray2bin #(

.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1)

u_gray2bin_rd (

.gray ( syn_wr_gray_ptr_rd_clk ),

.bin ( syn_wr_bin_ptr_rd_clk )

);

//******************************************************************

// FIFO讀空標(biāo)志位的產(chǎn)生和讀FIFO數(shù)據(jù)量的計(jì)數(shù)

//******************************************************************

assign rd_empty_w = (next_rd_gray_ptr == syn_wr_gray_ptr_rd_clk);

assign rd_cnt_w = syn_wr_bin_ptr_rd_clk - next_rd_bin_ptr;

always @(posedge rd_clk or negedge rd_rst_n)

begin

if(rd_rst_n == 1‘b0)

begin

rd_empty 《= 1’b0;

rd_cnt 《= {(C_FIFO_DEPTH_WIDTH+1){1‘b0}};

end

else

begin

rd_empty 《= rd_empty_w;

rd_cnt 《= rd_cnt_w;

end

end

endmodule

其中,模塊gray2bin是格雷碼轉(zhuǎn)二進(jìn)制碼,模塊bin2gray是二進(jìn)制碼轉(zhuǎn)格雷碼,詳情見(jiàn)上一篇博客,地址:http://blog.chinaaet.com/crazybird/p/5100000866 。模塊double_syn_ff是兩級(jí)寄存器,用于同步信號(hào),對(duì)應(yīng)的Verilog HDL實(shí)現(xiàn)如下所示:

**------------------------------文件信息--------------------------------

** 文件名: double_syn_ff.v

** 創(chuàng)建者: CrazyBird

** 創(chuàng)建日期: 2016-1-16

** 版本號(hào): v1.0

** 功能描述: 對(duì)輸入信號(hào)進(jìn)行兩級(jí)同步后輸出

**

***********************************************************************/

// synopsys translate_off

`timescale 1 ns / 1 ps

// synopsys translate_on

module double_syn_ff(

rst_n,

clk,

din,

dout

);

//******************************************************************

// 參數(shù)定義

//******************************************************************

parameter C_DATA_WIDTH = 8;

//******************************************************************

// 端口定義

//******************************************************************

input rst_n;

input clk;

input [C_DATA_WIDTH-1:0] din;

output reg [C_DATA_WIDTH-1:0] dout;

//******************************************************************

// 內(nèi)部變量定義

//******************************************************************

reg [C_DATA_WIDTH-1:0] data_r;

//******************************************************************

// 對(duì)輸入信號(hào)進(jìn)行兩級(jí)同步后輸出

//******************************************************************

always @(posedge clk or negedge rst_n)

begin

if(rst_n == 1’b0)

{dout,data_r} 《= {(2*C_DATA_WIDTH){1‘b0}};

else

{dout,data_r} 《= {data_r,din};

end

endmodule

由于字?jǐn)?shù)的限制,異步FIFO的功能驗(yàn)證放在下一篇博文中吧?。?!

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5274

    瀏覽量

    119663
  • fifo
    +關(guān)注

    關(guān)注

    3

    文章

    386

    瀏覽量

    43466

原文標(biāo)題:【原創(chuàng)博文】基于FPGA的異步FIFO設(shè)計(jì)

文章出處:【微信號(hào):ChinaAET,微信公眾號(hào):電子技術(shù)應(yīng)用ChinaAET】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于FPGA異步FIFO的實(shí)現(xiàn)

    大家好,又到了每日學(xué)習(xí)的時(shí)間了,今天我們來(lái)聊一聊基于FPGA異步FIFO的實(shí)現(xiàn)。 一、FIFO簡(jiǎn)介 FIFO是英文First In Fir
    的頭像 發(fā)表于 06-21 11:15 ?6436次閱讀
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>的實(shí)現(xiàn)

    基于FPGA器件實(shí)現(xiàn)異步FIFO讀寫(xiě)系統(tǒng)的設(shè)計(jì)

    異步 FIFO 讀寫(xiě)分別采用相互異步的不同時(shí)鐘。在現(xiàn)代集成電路芯片中,隨著設(shè)計(jì)規(guī)模的不斷擴(kuò)大,一個(gè)系統(tǒng)中往往含有數(shù)個(gè)時(shí)鐘,多時(shí)鐘域帶來(lái)的一個(gè)問(wèn)題就是,如何設(shè)計(jì)異步時(shí)鐘之間的接口電路。
    發(fā)表于 07-16 17:41 ?1195次閱讀
    基于<b class='flag-5'>FPGA</b>器件實(shí)現(xiàn)<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>讀寫(xiě)系統(tǒng)的設(shè)計(jì)

    怎么解決異步FIFO設(shè)計(jì)的難點(diǎn)?

    FIFO的基本結(jié)構(gòu)和工作原理異步FIFO設(shè)計(jì)中的問(wèn)題與解決辦法FPGA內(nèi)部軟異步FIFO設(shè)計(jì)
    發(fā)表于 04-08 07:07

    異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì)

    首先介紹異步FIFO 的概念、應(yīng)用及其結(jié)構(gòu),然后分析實(shí)現(xiàn)異步FIFO的難點(diǎn)問(wèn)題及其解決辦法; 在傳統(tǒng)設(shè)計(jì)的基礎(chǔ)上提出一種新穎的電路結(jié)構(gòu)并對(duì)其進(jìn)行綜合仿真和
    發(fā)表于 04-16 09:25 ?46次下載

    高速異步FIFO的設(shè)計(jì)與實(shí)現(xiàn)

    本文主要研究了用FPGA 芯片內(nèi)部的EBRSRAM 來(lái)實(shí)現(xiàn)異步FIFO 設(shè)計(jì)方案,重點(diǎn)闡述了異步FIFO 的標(biāo)志信號(hào)——空/滿(mǎn)狀態(tài)的設(shè)計(jì)思路
    發(fā)表于 01-13 17:11 ?40次下載

    Camera Link接口的異步FIFO設(shè)計(jì)與實(shí)現(xiàn)

    介紹了異步FIFO在Camera Link接口中的應(yīng)用,將Camera Link接口中的幀有效信號(hào)FVAL和行有效信號(hào)LVAL引入到異步FIFO的設(shè)計(jì)中。分析了
    發(fā)表于 07-28 16:08 ?32次下載

    異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì)

    摘要:首先介紹異步FIFO的概念、應(yīng)用及其結(jié)構(gòu),然后分析實(shí)現(xiàn)異步FIFO的難點(diǎn)問(wèn)題及其解決辦法;在傳統(tǒng)設(shè)計(jì)的基礎(chǔ)上提出一種新穎的電路結(jié)構(gòu)并對(duì)其進(jìn)行
    發(fā)表于 06-20 12:46 ?3826次閱讀
    <b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>結(jié)構(gòu)及<b class='flag-5'>FPGA</b>設(shè)計(jì)

    異步FIFOFPGA與DSP通信中的運(yùn)用

    文中給出了異步FIFO的實(shí)現(xiàn)代碼和FPGA與DSP的硬件連接電路。經(jīng)驗(yàn)證,利用異步FIFO的方法,在FP
    發(fā)表于 12-12 14:28 ?51次下載
    <b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>在<b class='flag-5'>FPGA</b>與DSP通信中的運(yùn)用

    異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì)

    異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì),解決亞穩(wěn)態(tài)的問(wèn)題
    發(fā)表于 11-10 15:21 ?4次下載

    異步FIFOFPGA與DSP通信中的運(yùn)用

    異步FIFOFPGA與DSP通信中的運(yùn)用
    發(fā)表于 05-19 11:17 ?0次下載

    基于異步FIFOFPGA與DSP通信中的運(yùn)用

    基于異步FIFOFPGA與DSP通信中的運(yùn)用
    發(fā)表于 10-19 10:30 ?10次下載
    基于<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>在<b class='flag-5'>FPGA</b>與DSP通信中的運(yùn)用

    異步FIFOFPGA與DSP通信中的應(yīng)用解析

    摘要 利用異步FIFO實(shí)現(xiàn)FPGA與DSP進(jìn)行數(shù)據(jù)通信的方案。FPGA在寫(xiě)時(shí)鐘的控制下將數(shù)據(jù)寫(xiě)入FIFO,再與DSP進(jìn)行握手后,DSP通過(guò)E
    發(fā)表于 10-30 11:48 ?2次下載
    <b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>在<b class='flag-5'>FPGA</b>與DSP通信中的應(yīng)用解析

    基于FPGA異步FIFO設(shè)計(jì)方法詳解

    在現(xiàn)代電路設(shè)計(jì)中,一個(gè)系統(tǒng)往往包含了多個(gè)時(shí)鐘,如何在異步時(shí)鐘間傳遞數(shù)據(jù)成為一個(gè)很重要的問(wèn)題,而使用異步FIFO可以有效地解決這個(gè)問(wèn)題。異步FIFO
    發(fā)表于 07-17 08:33 ?8272次閱讀
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>設(shè)計(jì)方法詳解

    Xilinx異步FIFO的大坑

    FIFOFPGA處理跨時(shí)鐘和數(shù)據(jù)緩存的必要IP,可以這么說(shuō),只要是任意一個(gè)成熟的FPGA涉及,一定會(huì)涉及到FIFO。但是我在使用異步
    發(fā)表于 03-12 06:01 ?12次下載
    Xilinx<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>的大坑

    同步FIFO異步FIFO的區(qū)別 同步FIFO異步FIFO各在什么情況下應(yīng)用

    同步FIFO異步FIFO的區(qū)別 同步FIFO異步FIFO各在什么情況下應(yīng)用? 1. 同步
    的頭像 發(fā)表于 10-18 15:23 ?1552次閱讀