1、異步FIFO
在ASIC設(shè)計或者FPGA設(shè)計中,我們常常使用異步fifo(first in first out)(下文簡稱為afifo)進行數(shù)據(jù)流的跨時鐘,可以說沒使用過afifo的Designer,其設(shè)計經(jīng)歷是不完整的。廢話不多說,直接上接口信號說明。
2、afifo接口信號說明
如下表格為常見的afifo接口信號,非必須指的部分場景的afifo可能不存在此信號。不同公司對afifo接口的設(shè)計可能不一樣,但是基本都包含了如下接口:wr表示write,寫側(cè)時鐘域信號,rd表示read,讀側(cè)時鐘域信號。
信號名稱 | 位寬 | 必要性 | 含義 |
almost_full | 1 | 非必須 | 將滿信號,1表示afifo快滿了,當(dāng)afifo的有效數(shù)量大于配置時,置1 |
full | 1 | 非必須 | afifo滿信號,1表示afifo已滿 |
empty | 1 | 非必須 | 1表示 |
rd_data | [DATA_WIDTH-1:0] | 必須 | 有效數(shù)據(jù) |
ovf_int | 1 | 非必須 | 1表示上溢出,即afifo滿了還有數(shù)據(jù)寫入 |
udf_int | 1 | 非必須 | 1表示下溢出,即afifo空了外部邏輯還產(chǎn)生了讀使能 |
data_count | [ADDR_WIDTH:0] | 非必須 | afifo存儲的數(shù)據(jù)量 |
cfg_almost_full_value | [ADDR_WIDTH:0] | 非必須 | 將滿配置信號,一般由配置寄存器模塊提供驅(qū)動 |
wr_rst_n | 1 | 必須 | 寫側(cè)復(fù)位 |
wr_clk | 1 | 必須 | 寫側(cè)時鐘 |
wr_en | 1 | 必須 | 寫使能,1表示有數(shù)據(jù)寫入 |
wr_data | [DATA_WIDTH-1:0] | 必須 | 寫數(shù)據(jù) |
rd_rst_n | 1 | 必須 | 讀時鐘與復(fù)位 |
rd_clk | 1 | 必須 | 讀時鐘 |
rd_en | 1 | 必須 | 讀使能 |
3、設(shè)計原理
為了方便描述,本章節(jié)將以深度為8的afifo進行講解,其中讀寫地址位寬為3,格雷碼地址位寬為4。
圖1 afifo結(jié)構(gòu)圖(來自eetop ThinkSpark)
圖2:讀寫地址計算圖
(1)存儲模塊:
中間區(qū)域為memory存儲模塊,用于存儲數(shù)據(jù)data,要么是1R1W的ram,要么是普通的寄存器。項目自研代碼中,存儲模塊通常使用1R1W的ram,其需要memory生成器生成,需要與制造工藝匹配。而在soft IP中,針對小規(guī)格的afifo,為了方便,常常使用寄存器作為afifo的存儲。
(2)寫地址產(chǎn)生邏輯
寫地址waddr在wr_clk時鐘域產(chǎn)生,有兩個作用,作為存儲模塊的寫地址并且產(chǎn)生格雷碼waddr_gray。此種需要注意:waddr是遞增的,且會翻轉(zhuǎn)。如果afifo深度為8(n),則waddr位寬為3(log2(n) ),waddr計數(shù)到7后,再次寫入則翻轉(zhuǎn)為0。
(3)讀地址產(chǎn)生邏輯
讀地址raddr在rd_clk時鐘域產(chǎn)生,有兩個作用,作為存儲模塊的讀地址并且產(chǎn)生格雷碼raddr_gray。此種需要注意:raddr是遞增的,且會翻轉(zhuǎn)。如果afifo深度為8(n),則raddr位寬為3(log2(n) ),raddr計數(shù)到7后,再次讀出則翻轉(zhuǎn)為0。
(4)讀地址同步
使用2級或者3級單bit同步器Synchronizer將讀地址格雷碼raddr_gray同步到wr_clk時鐘域得到raddr_gray_sync,raddr_gray_sync進行格雷碼逆轉(zhuǎn)成二進制編碼得到raddr_sync,用于產(chǎn)生將滿信號和滿信號。
在fpga設(shè)計中,2級單bit同步器Synchronizer就是2個串聯(lián)的寄存器,在ASIC設(shè)計中,通常是定制的cell(會將兩個/三個寄存器擺放靠得很近)。
(5)寫地址同步器
使用2級或者3級單bit同步器Synchronizer將寫地址格雷碼waddr_gray同步到rd_clk時鐘域得到waddr_gray_sync,waddr_gray_sync進行格雷碼逆轉(zhuǎn)成二進制編碼得到waddr_sync,用于產(chǎn)生將空信號和空信號。
(6)滿信號產(chǎn)生邏輯
此模塊首先計算在wr_clk時鐘域的剩余可寫afifo深度,即wr_gap[3:0]=raddr_sync[2:0]+4’d8(FIFO深度)-waddr[2:0],然后根據(jù)wr_gap[3:0]產(chǎn)生amost_full和full信號
always @(posedge wr_clk or negedge wr_rst_n) if(~wr_rst_n) full <= 1'b0; else full <= (!(|wr_gap)) || ((wr_gap==1)&wr_en);
always @(posedge wr_clk or negedge wr_rst_n) if(~wr_rst_n) begin almost_full <= 1'b0; end else begin if( wr_data_cnt>=cfg_almost_full_value ) almost_full <= 1'b1; else almost_full <= almost_full; end
(7)空信號產(chǎn)生邏輯
此模塊首先計算在rd_clk時鐘域的可讀afifo深度,即assign {ovf_nc1,rd_gap} = waddr_sync - raddr,然后根據(jù)rd_gap[3:0]產(chǎn)生empty信號。
always @(posedge rd_clk or negedge rd_rst_n) if(~rd_rst_n) empty <= 1'b1; else empty <= (!(|rd_gap)) || ((rd_gap==1)&rd_en);? ? ? ? ?
4、重點說明
(1)格雷碼的優(yōu)勢
格雷碼的特點就是在遞增,遞減,或者翻轉(zhuǎn)過程中,只會有1個bit位發(fā)生變化。因此單bit同步器Synchronizer同步后,只有存在變化的那一個bit可能會發(fā)生亞穩(wěn)態(tài)。即使發(fā)生了亞穩(wěn)態(tài),體現(xiàn)的結(jié)果要么是0,要么是1,在格雷碼上的同步效果就是當(dāng)前clk周期沒有同步(相當(dāng)于delay了一個目的周期)到或者當(dāng)前周期已采樣到。
同時它也有自己的局限性,那就是循環(huán)計數(shù)深度必須是2的n次冪(也可以不是2的n次冪哦),否則就失去了每次只變化一位的特性。深度為16的二進制及格雷碼遞變表如下:
Binary Gray
0 0000 0000
1 0001 0001
2 0010 0011
3 0011 0010
4 0100 0110
5 0101 0111
6 0110 0101
7 0111 0100
8 1000 1100
9 1001 1101
10 1010 1111
11 1011 1110
12 1100 1010
13 1101 1011
14 1110 1001
15 1111 1000
0 0000 0000
(2)空信號計算方法的妙處
在rd_clk時鐘域計算可讀數(shù)據(jù)量以及empty信號,看圖2會發(fā)現(xiàn),實際rd_gap永遠小于等于真實可讀數(shù)據(jù)量,能夠保證empty為0時永遠不會發(fā)生空讀現(xiàn)象,即afifo沒有數(shù)據(jù),也進行了讀操作。
(3)滿信號計算方法的妙處
在wd_clk時鐘域計算可寫數(shù)據(jù)量以及full信號,看圖2會發(fā)現(xiàn),實際wr_gap永遠小于等于真實可寫數(shù)據(jù)量,能夠保證full為0時永遠不會發(fā)生寫溢出現(xiàn)象,即full為0時,afifo可能存在空閑位置。
(4)格雷碼轉(zhuǎn)二進制代碼
function [ADDR_WIDTH:0] gray2bin; //to change the gray code to bin code input [ADDR_WIDTH:0] gray_in; //input gray code reg [ADDR_WIDTH:0] gray_code; //reg gray reg [ADDR_WIDTH:0] bin_code; //bin code result integer i,j; //integer reg tmp; //tmp begin gray_code = gray_in; for(i=0;i<=ADDR_WIDTH;i=i+1) begin tmp=1'b0; for(j=i;j<=ADDR_WIDTH;j=j+1) tmp=gray_code[j]^tmp; bin_code[i]=tmp; end gray2bin= bin_code; end endfunction
(5)二進制轉(zhuǎn)格雷碼
always @(posedge rd_clk or negedge rd_rst_n) if(~rd_rst_n) raddr_gray <= {(ADDR_WIDTH + 1){1'b0}}; else raddr_gray <= raddr ^ {1'b0,raddr[ADDR_WIDTH:1]};
5、結(jié)束語
Afifo代碼寫出來還不夠,還需要設(shè)置約束條件,后期我們會再講講afifo的格雷碼如何約束。
-
FPGA
+關(guān)注
關(guān)注
1650文章
22204瀏覽量
626668 -
asic
+關(guān)注
關(guān)注
34文章
1263瀏覽量
123500 -
接口
+關(guān)注
關(guān)注
33文章
9257瀏覽量
155401 -
fifo
+關(guān)注
關(guān)注
3文章
402瀏覽量
45274 -
時鐘
+關(guān)注
關(guān)注
11文章
1946瀏覽量
134103
原文標(biāo)題:
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于FPGA器件實現(xiàn)異步FIFO讀寫系統(tǒng)的設(shè)計

關(guān)于異步fifo的安全問題:
使用Xilinx異步FIFO常見的坑
異步FIFO的設(shè)計分析及詳細代碼

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

基于異步FIFO結(jié)構(gòu)原理

關(guān)于一種面向異步FIFO的低開銷容錯機制研究

如何解決異步FIFO跨時鐘域亞穩(wěn)態(tài)問題?
Xilinx異步FIFO的大坑

異步fifo詳解
Verilog電路設(shè)計之單bit跨時鐘域同步和異步FIFO
同步FIFO和異步FIFO的區(qū)別 同步FIFO和異步FIFO各在什么情況下應(yīng)用
同步FIFO和異步FIFO區(qū)別介紹

評論