日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于FPGA的异步FIFO设计

發(fā)布時間:2023/12/6 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于FPGA的异步FIFO设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天要介紹的異步FIFO,可以有不同的讀寫時鐘,即不同的時鐘域。由于異步FIFO沒有外部地址端口,因此內(nèi)部采用讀寫指針并順序讀寫,即先寫進FIFO的數(shù)據(jù)先讀取(簡稱先進先出)。這里的讀寫指針是異步的,處理不同的時鐘域,而異步FIFO的空滿標志位是根據(jù)讀寫指針的情況得到的。為了得到正確的空滿標志位,需要對讀寫指針進行同步。一般情況下,如果一個時鐘域的信號直接給另一個時鐘域采集,可能會產(chǎn)生亞穩(wěn)態(tài),亞穩(wěn)態(tài)的產(chǎn)生對設(shè)計而言是致命的。為了減少不同時鐘域間的亞穩(wěn)態(tài)問題,我們先對它進行兩拍寄存同步,如圖1所示。當然,對異步信號的寄存越多,產(chǎn)生亞穩(wěn)態(tài)的概率就越小,但延時越多。不過一般情況下,寄存兩拍就夠了。為了繼續(xù)減少亞穩(wěn)態(tài)產(chǎn)生的概率,在對異步信號同步之前,將其轉(zhuǎn)換為格雷碼,使其每個狀態(tài)只有一個位在變化。例如,假設(shè)N位二進制變量產(chǎn)生的亞穩(wěn)態(tài)概率為a,那么二進制轉(zhuǎn)換成格雷碼后其產(chǎn)生的亞穩(wěn)態(tài)概率則為a/N。

圖1 ?對異步信號用兩級寄存器同步

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

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

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

????寫時鐘域:

????(1)根據(jù)寫使能wr_en和寫滿標志位wr_full產(chǎn)生二進制寫指針

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

????(3)由二進制寫指針轉(zhuǎn)換成格雷碼寫指針

????(4)對格雷碼讀指針在寫時鐘域中進行兩級同步得同步后格雷碼讀指針

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

????(6)步驟(3)與步驟(4)比較得寫滿標志位wr_full

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

????讀時鐘域:

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

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

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

????(11)對格雷碼寫指針在讀時鐘域中進行兩級同步得同步后格雷碼寫指針

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

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

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

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

/*******************************版權(quán)申明******************************** **?????????????????????電子技術(shù)應(yīng)用網(wǎng)站,?CrazyBird **?????http://www.chinaaet.com,?http://blog.chinaaet.com/crazybird ** **------------------------------文件信息-------------------------------- **?文件名:??????????asyn_fifo.v **?創(chuàng)建者:??????????CrazyBird **?創(chuàng)建日期:????????2016-1-16 **?版本號:???????????v1.0 **?功能描述:????????異步FIFO,用于處理不同的時鐘域 **??????????????????? ***********************************************************************/ //?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的讀寫//******************************************************************//??寫RAMalways?@(posedge?wr_clk)beginif((wr_en?&?~wr_full)?==?1'b1)mem[wr_addr]?<=?wr_data;end//??讀RAMassign?rd_data?=?mem[rd_addr];//******************************************************************//??二進制寫指針的產(chǎn)生//******************************************************************assign?next_wr_bin_ptr?=?wr_bin_ptr?+?(wr_en?&?~wr_full);always?@(posedge?wr_clk?or?negedge?wr_rst_n)beginif(wr_rst_n?==?1'b0)wr_bin_ptr?<=?{(C_FIFO_DEPTH_WIDTH+1){1'b0}};elsewr_bin_ptr?<=?next_wr_bin_ptr;end//******************************************************************//??RAM寫地址的產(chǎn)生//******************************************************************assign?wr_addr?=?wr_bin_ptr[C_FIFO_DEPTH_WIDTH-1:0];//******************************************************************//??二進制寫指針轉(zhuǎn)換成格雷碼寫指針//******************************************************************bin2gray?#(.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1))u_bin2gray_wr?(.bin????(???next_wr_bin_ptr?????),.gray???(???next_wr_gray_ptr????));//******************************************************************//??對格雷碼讀指針在寫時鐘域中進行兩級同步//******************************************************************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)換成同步后的二進制讀指針//******************************************************************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寫滿標志位的產(chǎn)生和寫FIFO數(shù)據(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)beginif(wr_rst_n?==?1'b0)beginwr_full?<=?1'b0;wr_cnt??<=?{(C_FIFO_DEPTH_WIDTH+1){1'b0}};endelsebeginwr_full?<=?wr_full_w;wr_cnt??<=?wr_cnt_w;endend//******************************************************************//??二進制讀指針的產(chǎn)生//******************************************************************assign?next_rd_bin_ptr?=?rd_bin_ptr?+?(rd_en?&?~rd_empty);always?@(posedge?rd_clk?or?negedge?rd_rst_n)beginif(rd_rst_n?==?1'b0)rd_bin_ptr?<=?{(C_FIFO_DEPTH_WIDTH+1){1'b0}};elserd_bin_ptr?<=?next_rd_bin_ptr;end//******************************************************************//??RAM讀地址的產(chǎn)生//******************************************************************assign?rd_addr?=?rd_bin_ptr[C_FIFO_DEPTH_WIDTH-1:0];//******************************************************************//??二進制讀指針轉(zhuǎn)換成格雷碼讀指針//******************************************************************bin2gray?#(.C_DATA_WIDTH(C_FIFO_DEPTH_WIDTH+1))u_bin2gray_rd?(.bin????(???next_rd_bin_ptr?????),.gray???(???next_rd_gray_ptr????));//******************************************************************//??對格雷碼寫指針在讀時鐘域中進行兩級同步//******************************************************************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??));//******************************************************************//??同步后的格雷碼寫指針轉(zhuǎn)換成同步后的二進制寫指針//******************************************************************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讀空標志位的產(chǎn)生和讀FIFO數(shù)據(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)beginif(rd_rst_n?==?1'b0)beginrd_empty?<=?1'b0;rd_cnt???<=?{(C_FIFO_DEPTH_WIDTH+1){1'b0}};endelsebeginrd_empty?<=?rd_empty_w;rd_cnt???<=?rd_cnt_w;endendendmodule

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

/*******************************版權(quán)申明******************************** **?????????????????????電子技術(shù)應(yīng)用網(wǎng)站,?CrazyBird **?????http://www.chinaaet.com,?http://blog.chinaaet.com/crazybird ** **------------------------------文件信息-------------------------------- **?文件名:??????????double_syn_ff.v **?創(chuàng)建者:??????????CrazyBird **?創(chuàng)建日期:????????2016-1-16 **?版本號:???????????v1.0 **?功能描述:????????對輸入信號進行兩級同步后輸出 **??????????????????? ***********************************************************************/ //?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;//******************************************************************//??對輸入信號進行兩級同步后輸出//******************************************************************always?@(posedge?clk?or?negedge?rst_n)beginif(rst_n?==?1'b0){dout,data_r}?<=?{(2*C_DATA_WIDTH){1'b0}};else{dout,data_r}?<=?{data_r,din};endendmodule

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

轉(zhuǎn)載:http://blog.chinaaet.com/crazybird/p/5100000872

總結(jié)

以上是生活随笔為你收集整理的基于FPGA的异步FIFO设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。