異步FIFO是一種先進(jìn)先出電路,用在需要實(shí)時(shí)數(shù)據(jù)接口的部分,用來存儲(chǔ)、緩沖在兩個(gè)異步時(shí)鐘之間的數(shù)據(jù)傳輸。異步FIFO與同步FIFO最大的不同在于異步FIFO讀寫時(shí)鐘不同,通常異步FIFO用來做數(shù)據(jù)的時(shí)鐘域轉(zhuǎn)換,F(xiàn)IFO設(shè)計(jì)中難度最大的地方在FIFO的空滿標(biāo)識(shí)的產(chǎn)生,對同步FIFO來說,由于讀寫指針的增加時(shí)鐘頻率相同,因此讀寫指針可以直接進(jìn)行比較產(chǎn)生出空滿標(biāo)志,而異步FIFO某由于讀寫兩端時(shí)鐘頻率不同,讀寫指針需要進(jìn)行時(shí)鐘域轉(zhuǎn)換后才能進(jìn)行比較,也就是讀時(shí)鐘域的讀地址要先轉(zhuǎn)到寫時(shí)鐘域,然后與寫時(shí)鐘域的寫地址進(jìn)行比較,而實(shí)際這種比較時(shí)存在一定風(fēng)險(xiǎn)的。
異步FIFO設(shè)計(jì)一般的結(jié)構(gòu)有:雙口存儲(chǔ)器、讀地址產(chǎn)生邏輯、寫地址產(chǎn)生邏輯、空/滿標(biāo)志產(chǎn)生邏輯四部分構(gòu)成。圖1是一種常用的異步FIFO設(shè)計(jì)方案,其中,讀地址(rptr)和空標(biāo)志(rempty)由讀時(shí)鐘(rclk)產(chǎn)生,而寫地址(wptr)和滿標(biāo)志(wfull)由寫時(shí)鐘(wclk)產(chǎn)生。把寫地址與讀地址相互比較以產(chǎn)生空/滿標(biāo)志。由于讀寫地址的變化由不同的時(shí)鐘產(chǎn)生,所以對FIFO空或滿的判斷是跨時(shí)鐘域的。如何避免異步傳輸帶來的亞穩(wěn)態(tài)以及正確地產(chǎn)生空/滿標(biāo)志是設(shè)計(jì)異步FIFO的難點(diǎn)。
圖1
在設(shè)計(jì)時(shí),需要弄清楚以下幾個(gè)方面:
1.首先確定輸入輸出接口,異步FIFO在一個(gè)時(shí)鐘域中進(jìn)行寫數(shù)據(jù)操作,而在另一個(gè)時(shí)鐘域中進(jìn)行讀數(shù)據(jù)操作,所以在寫數(shù)據(jù)模塊,需要有寫數(shù)據(jù)wdata,寫時(shí)鐘wclk,寫復(fù)位wrst_n,寫請求wreq,寫滿標(biāo)志wfull;在讀數(shù)據(jù)模塊,需要有讀數(shù)據(jù)rdata,讀時(shí)鐘rclk,讀復(fù)位rrst_n,讀請求rreq,讀空標(biāo)志rempty。其中rdata,rempty,wfull為輸出信號(hào),其余為輸入信號(hào)。
其FIFO用來存儲(chǔ)16*8數(shù)據(jù)(數(shù)據(jù)寬為8,數(shù)據(jù)深度為16)的頂層模塊如下:
//異步FIFO緩存16*8數(shù)據(jù),即數(shù)據(jù)寬度為8,深度為 16//
moduleyibufifo(rdata,rempty,rrep,rclk,rrst_n,wdata,wfull,wrep,wclk,wrst_n);
input wclk,wrep,wrst_n;
input rclk,rrep,rrst_n;
input[7:0]wdata;
output[7:0]rdata;
output rempty,wfull;
wire wclk,wrep,wrst_n;
wire rclk,rrep,rrst_n;
wire [7:0]wdata;
wire [7:0]rdata;
wire [3:0]wptr,rptr;
wire [3:0]waddr,raddr;
wire aempty_n,afull_n;
ram i1(.wdata(wdata),//讀寫存儲(chǔ)模塊
.rdata(rdata),
.waddr(wptr),//地址與指針同步
.raddr(rptr),//
.wrep(wrep),
.wclk(wclk));
async_cmp i2(.aempty_n(aempty_n),//異步比較讀寫指針產(chǎn)生異步空滿標(biāo)志
.afull_n(afull_n),
.wptr(wptr),
.rptr(rptr),
.wrst_n(wrst_n));
rptr_empty2i3(.rempty(rempty),//根據(jù)rclk產(chǎn)生讀指針rptr和空標(biāo)志rempty
.rptr(rptr),
.aempty_n(aempty_n),
.rrep(rrep),
.rclk(rclk),
.rrst_n(rrst_n));
wptr_full2 i4(.wfull(wfull),//根據(jù)wclk產(chǎn)生寫指針wptr和滿標(biāo)志wfull
.wptr(wptr),
.afull_n(afull_n),
.wrep(wrep),
.wclk(wclk),
.wrst_n(wrst_n));
endmodule
頂層模塊圖:
其中
2.1讀寫地址產(chǎn)生邏輯(本設(shè)計(jì)中讀寫地址與讀寫指針同步)
讀寫地址線一般有多位,如果在不同的時(shí)鐘域內(nèi)直接同步二進(jìn)制碼的地址指針,則有可能產(chǎn)生亞穩(wěn)態(tài)。例如,讀指針從011變化到100時(shí),所有位都要變化,讀指針的每一位在讀時(shí)鐘的作用下,跳變不一致,即產(chǎn)生毛刺。如果寫時(shí)鐘恰好在讀指針的變化時(shí)刻采樣,得到的采樣信號(hào)可能是000~111中的任何一個(gè),從而導(dǎo)致空/滿信號(hào)判斷錯(cuò)誤。由實(shí)踐可知,同步多個(gè)異步輸入信號(hào)出現(xiàn)亞穩(wěn)態(tài)的概率遠(yuǎn)遠(yuǎn)大于同步一個(gè)異步信號(hào)的概率[3]。解決這一問題的有效方法是采用格雷碼。格雷碼的主要特點(diǎn)是相鄰的兩個(gè)編碼之間只有一位變化。圖2是格雷碼產(chǎn)生的邏輯框圖。在讀使能或?qū)懯鼓苄盘?hào)有效、并且空/滿標(biāo)志無效的情況下,讀寫指針開始累加,進(jìn)行FIFO讀或?qū)懖僮?。二進(jìn)制碼與格雷碼的轉(zhuǎn)換是一個(gè)“異或”運(yùn)算:gnext=(bnext>>1)^bnext。格雷碼gnext經(jīng)寄存器輸出格雷碼指針ptr。這種方法采用了兩組寄存器,雖然面積較大,但是有助于提高系統(tǒng)的工作頻率。
圖2
alwa
愛華網(wǎng)


