1、異步FIFO
在ASIC設(shè)計(jì)或者FPGA設(shè)計(jì)中,我們常常使用異步fifo(first in first out)(下文簡稱為afifo)進(jìn)行數(shù)據(jù)流的跨時(shí)鐘,可以說沒使用過afifo的Designer,其設(shè)計(jì)經(jīng)歷是不完整的。廢話不多說,直接上接口信號(hào)說明。
2、afifo接口信號(hào)說明
如下表格為常見的afifo接口信號(hào),非必須指的部分場景的afifo可能不存在此信號(hào)。不同公司對(duì)afifo接口的設(shè)計(jì)可能不一樣,但是基本都包含了如下接口:wr表示write,寫側(cè)時(shí)鐘域信號(hào),rd表示read,讀側(cè)時(shí)鐘域信號(hào)。
信號(hào)名稱 | 位寬 | 必要性 | 含義 |
almost_full | 1 | 非必須 | 將滿信號(hào),1表示afifo快滿了,當(dāng)afifo的有效數(shù)量大于配置時(shí),置1 |
full | 1 | 非必須 | afifo滿信號(hào),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存儲(chǔ)的數(shù)據(jù)量 |
cfg_almost_full_value | [ADDR_WIDTH:0] | 非必須 | 將滿配置信號(hào),一般由配置寄存器模塊提供驅(qū)動(dòng) |
wr_rst_n | 1 | 必須 | 寫側(cè)復(fù)位 |
wr_clk | 1 | 必須 | 寫側(cè)時(shí)鐘 |
wr_en | 1 | 必須 | 寫使能,1表示有數(shù)據(jù)寫入 |
wr_data | [DATA_WIDTH-1:0] | 必須 | 寫數(shù)據(jù) |
rd_rst_n | 1 | 必須 | 讀時(shí)鐘與復(fù)位 |
rd_clk | 1 | 必須 | 讀時(shí)鐘 |
rd_en | 1 | 必須 | 讀使能 |
3、設(shè)計(jì)原理
為了方便描述,本章節(jié)將以深度為8的afifo進(jìn)行講解,其中讀寫地址位寬為3,格雷碼地址位寬為4。
圖1 afifo結(jié)構(gòu)圖(來自eetop ThinkSpark)
圖2:讀寫地址計(jì)算圖
(1)存儲(chǔ)模塊:
中間區(qū)域?yàn)閙emory存儲(chǔ)模塊,用于存儲(chǔ)數(shù)據(jù)data,要么是1R1W的ram,要么是普通的寄存器。項(xiàng)目自研代碼中,存儲(chǔ)模塊通常使用1R1W的ram,其需要memory生成器生成,需要與制造工藝匹配。而在soft IP中,針對(duì)小規(guī)格的afifo,為了方便,常常使用寄存器作為afifo的存儲(chǔ)。
(2)寫地址產(chǎn)生邏輯
寫地址waddr在wr_clk時(shí)鐘域產(chǎn)生,有兩個(gè)作用,作為存儲(chǔ)模塊的寫地址并且產(chǎn)生格雷碼waddr_gray。此種需要注意:waddr是遞增的,且會(huì)翻轉(zhuǎn)。如果afifo深度為8(n),則waddr位寬為3(log2(n) ),waddr計(jì)數(shù)到7后,再次寫入則翻轉(zhuǎn)為0。
(3)讀地址產(chǎn)生邏輯
讀地址raddr在rd_clk時(shí)鐘域產(chǎn)生,有兩個(gè)作用,作為存儲(chǔ)模塊的讀地址并且產(chǎn)生格雷碼raddr_gray。此種需要注意:raddr是遞增的,且會(huì)翻轉(zhuǎn)。如果afifo深度為8(n),則raddr位寬為3(log2(n) ),raddr計(jì)數(shù)到7后,再次讀出則翻轉(zhuǎn)為0。
(4)讀地址同步
使用2級(jí)或者3級(jí)單bit同步器Synchronizer將讀地址格雷碼raddr_gray同步到wr_clk時(shí)鐘域得到raddr_gray_sync,raddr_gray_sync進(jìn)行格雷碼逆轉(zhuǎn)成二進(jìn)制編碼得到raddr_sync,用于產(chǎn)生將滿信號(hào)和滿信號(hào)。
在fpga設(shè)計(jì)中,2級(jí)單bit同步器Synchronizer就是2個(gè)串聯(lián)的寄存器,在ASIC設(shè)計(jì)中,通常是定制的cell(會(huì)將兩個(gè)/三個(gè)寄存器擺放靠得很近)。
(5)寫地址同步器
使用2級(jí)或者3級(jí)單bit同步器Synchronizer將寫地址格雷碼waddr_gray同步到rd_clk時(shí)鐘域得到waddr_gray_sync,waddr_gray_sync進(jìn)行格雷碼逆轉(zhuǎn)成二進(jìn)制編碼得到waddr_sync,用于產(chǎn)生將空信號(hào)和空信號(hào)。
(6)滿信號(hào)產(chǎn)生邏輯
此模塊首先計(jì)算在wr_clk時(shí)鐘域的剩余可寫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信號(hào)
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)空信號(hào)產(chǎn)生邏輯
此模塊首先計(jì)算在rd_clk時(shí)鐘域的可讀afifo深度,即assign {ovf_nc1,rd_gap} = waddr_sync - raddr,然后根據(jù)rd_gap[3:0]產(chǎn)生empty信號(hào)。
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、重點(diǎn)說明
(1)格雷碼的優(yōu)勢
格雷碼的特點(diǎn)就是在遞增,遞減,或者翻轉(zhuǎn)過程中,只會(huì)有1個(gè)bit位發(fā)生變化。因此單bit同步器Synchronizer同步后,只有存在變化的那一個(gè)bit可能會(huì)發(fā)生亞穩(wěn)態(tài)。即使發(fā)生了亞穩(wěn)態(tài),體現(xiàn)的結(jié)果要么是0,要么是1,在格雷碼上的同步效果就是當(dāng)前clk周期沒有同步(相當(dāng)于delay了一個(gè)目的周期)到或者當(dāng)前周期已采樣到。
同時(shí)它也有自己的局限性,那就是循環(huán)計(jì)數(shù)深度必須是2的n次冪(也可以不是2的n次冪哦),否則就失去了每次只變化一位的特性。深度為16的二進(jìn)制及格雷碼遞變表如下:
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)空信號(hào)計(jì)算方法的妙處
在rd_clk時(shí)鐘域計(jì)算可讀數(shù)據(jù)量以及empty信號(hào),看圖2會(huì)發(fā)現(xiàn),實(shí)際rd_gap永遠(yuǎn)小于等于真實(shí)可讀數(shù)據(jù)量,能夠保證empty為0時(shí)永遠(yuǎn)不會(huì)發(fā)生空讀現(xiàn)象,即afifo沒有數(shù)據(jù),也進(jìn)行了讀操作。
(3)滿信號(hào)計(jì)算方法的妙處
在wd_clk時(shí)鐘域計(jì)算可寫數(shù)據(jù)量以及full信號(hào),看圖2會(huì)發(fā)現(xiàn),實(shí)際wr_gap永遠(yuǎn)小于等于真實(shí)可寫數(shù)據(jù)量,能夠保證full為0時(shí)永遠(yuǎn)不會(huì)發(fā)生寫溢出現(xiàn)象,即full為0時(shí),afifo可能存在空閑位置。
(4)格雷碼轉(zhuǎn)二進(jì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)二進(jìn)制轉(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è)置約束條件,后期我們會(huì)再講講afifo的格雷碼如何約束。
-
FPGA
+關(guān)注
關(guān)注
1643文章
21975瀏覽量
614446 -
asic
+關(guān)注
關(guān)注
34文章
1243瀏覽量
122024 -
接口
+關(guān)注
關(guān)注
33文章
8956瀏覽量
153249 -
fifo
+關(guān)注
關(guān)注
3文章
400瀏覽量
44635 -
時(shí)鐘
+關(guān)注
關(guān)注
11文章
1885瀏覽量
132873
原文標(biāo)題:
文章出處:【微信號(hào):處芯積律,微信公眾號(hào):處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
基于FPGA器件實(shí)現(xiàn)異步FIFO讀寫系統(tǒng)的設(shè)計(jì)

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

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

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

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

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

異步FIFO之Verilog代碼實(shí)現(xiàn)案例
異步fifo詳解
Verilog電路設(shè)計(jì)之單bit跨時(shí)鐘域同步和異步FIFO
FIFO設(shè)計(jì)—異步FIFO

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

評(píng)論