李紅科,王慶春,余順園
(安康學院電子與信息工程學院,陜西安康 725000)
隨著集成電路的飛速發展,超大規模集成電路芯片中一個完整系統包含多個時鐘,不同時鐘域控制下,數據在傳輸或存儲之間會出現亞穩態現象。異步FIFO(Frist Input Frist Output)是解決跨時鐘域數據傳輸和存儲所引發亞穩態的有效方法之一。異步FIFO 在雷達、信號處理及多媒體技術等領域有著廣泛的應用[1-3]。
FIFO是一種先進先出的雙端口數據緩存器,和普通緩沖器區別在于FIFO沒有外部地址線,優點是減少輸入信號控制線,缺點是數據只能順序寫入、順序讀出[4-5]。圖1給出了異步FIFO內部結構圖,包括雙端口RAM存儲器、寫控制器、讀控制器、寫地址指針同步到讀時鐘域(W2R 同步器)、讀地址指針同步到寫時鐘域(R2W同步器)、讀狀態標志位和寫狀態標志位等部分[6-8]。

圖1 異步FIFO內部結構圖
寫控制器模塊:在寫時鐘和寫使能信號作用下,產生寫地址指針。
讀控制器模塊:在讀時鐘和讀使能信號作用下,產生讀地址指針。
R2W 同步器模塊:讀計數器同步到寫時鐘域,同步后計數器和寫二進制計數器比較用于產生滿標志位(full)信號條件。
W2R 同步器模塊:寫計數器同步到讀時鐘域,同步后計數器和讀二進制計數器比較用于產生空標志位(empty)信號條件。
寫狀態標志位模塊:寫時鐘控制下產生滿(full)信號。
讀狀態標志位模塊:讀時鐘控制下產生空(empty)信號。
異步FIFO 外部引腳如表1 所示。

表1 異步FIFO外部引腳
異步FIFO 設計過程中存在兩個關鍵技術問題:1)亞穩態;2)空/滿狀態標志位判斷及產生。在處理空/滿標志位問題上,目前最常用的方案是增加一位讀寫指針附加位,當讀寫指針最高位相同其余位也相同時,認為讀空,當讀寫指針最高位不相同其余位相同時,認為寫滿。
文中以寬度為8 位、深度為16 位的異步FIF0 為例,介紹亞穩態產生的原因以及降低亞穩態出現概率的方法,分析利用格雷碼和同步轉換來產生空/滿標志位的方法。
在所有數字器件中,寄存器都定義了一個信號時序要求,滿足時序要求的寄存器才能正確地在輸入端獲取數據、在輸出端產生數據[9]。為確保操作可靠,輸入數據在時鐘沿之前必須穩定一段時間(建立時間),并且在時鐘沿之后保持一段時間(保持時間),觸發器經過一個特定時鐘至輸出延時后有效。如果一個數據信號在變化之前不滿足觸發器建立和保持時間要求,觸發器輸出可能會進入亞穩態。亞穩態觸發器輸出值會在高低電平之間徘徊不定,如圖2 所示。

圖2 亞穩態的產生示意圖
雖然亞穩態在異步電路中無法避免,但是兩級同步器和格雷碼計數器可以降低亞穩態概率到可以接受的程度。
1)兩級同步器
圖3 中,clk1 和clk2 是異步時鐘,FF1和FF2組成兩級同步器[10-11],對不同時鐘域的輸入數據鎖存兩拍。一般情況下,兩級鎖存同步器是一級同步器出現亞穩態概率的平方,在大部分同步設計中,兩級同步器可以大大降低亞穩態出現概率[12]。

圖3 異步電路同步化處理
圖4 中,當clk1 和clk2 上升沿很近時,data0 在變化時,此時clk2 上升沿采集到一個正在變化的數值,data1 是個不確定值,FF1觸發器輸出處于亞穩態,經過1 個時鐘延時,data1 值趨于穩定,FF2在clk2 上升沿對data1 穩定值采樣,輸出data2 為確定值。雖然data1 在被clk2 上升沿采樣時也有處于亞穩態的可能,但是這種概率很小,經過兩級同步器能大大降低亞穩態概率[13-15]。兩級同步器設計程序如下:

圖4 兩級同步器消除亞穩態


2)格雷碼計數器
格雷碼是一種誤差最小化的可靠性編碼,可以極大地減少由一個狀態變化到下一個狀態時電路產生的誤差[11]。這種編碼方式是兩個相鄰碼之間只有一位變化,缺點是格雷碼是無權碼,不能直接用于計算、比較,需要轉換為二進制代碼計算。
亞穩態出現的原因是數據變化時建立和保持時間不夠,數據地址經過二級同步器后,地址指針采用格雷碼編碼,地址指針一次只能變化一位,通過這種可以有效減少亞穩態出現概率。
但是格雷碼指針不能直接比較產生空/滿標志位,要產生空/滿標志位,需要將格雷碼讀指針和寫指針轉換為相應二進制讀指針和寫指針進行比較。
格雷碼轉二進制碼方法是格雷碼最高位碼等于二進制最高位碼Bn-1=Gn-1,二進制次高位=二進制最高位與格雷碼次高位異或,依次將n位格雷碼轉換為二進制碼[11]。

為防止FIFO 誤操作,設置空/滿狀態標志位,當空狀態標志位empty=1時,FIFO 不能再讀出數據。當滿狀態標志位full=1 時FIFO 不能再寫入數據。因為FIF0位寬為8位,至少需要3位二進制數表示地址位。
讀空條件:寫指針(wr_pointer)=讀指針(rd_pointer),如圖5(a)所示。因為讀指針和寫指針變化是在不同時鐘下完成,不能直接比較,必須轉換到相同時鐘下進行二進制比較,將讀指針轉換為寫時鐘域,當讀指針等于寫指針(w2r_bincnt==rd_bincnt)時,empty=1,FIFO 讀空。
寫滿條件:對寫滿操作分兩種情況討論:1)一次性寫滿,當寫時鐘域下寫二進制指針指向最后一個存儲單元時,讀時鐘域下的二進制讀指針指向第一存儲單元時,(wr_pointer=15)&&(rd_pointer=0),full=1寫滿,如圖5(b)所示;2)經過多次寫滿,一次只向FIFO寫一部分數據,多次FIFO寫滿。例如第一次寫入12個數據,第一次讀出10 個數據,第二次再寫入14 個數據時寫滿。當寫時鐘域下寫指針指向第n個存儲單元,寫指針同步到讀時鐘域下的二進制寫指針指向存在單元第n+1 個存儲單元(wr_pointer=n)&&(rd_pointer=n+1)時,full=1,FIFO寫滿,如圖5(c)所示。

圖5 異步FIFO空/滿狀態產生邏輯圖
整體設計包括:FIFO 存儲器設計模塊、寫計數器同步讀時鐘域模塊、讀計數器同步寫時鐘域模塊、空標志產生模塊、滿標志產生模塊和格雷碼計數器模塊[16-19]。
FIFO 雙端口RAM 模塊設計代碼如下:

寫計數器同步讀時鐘域模塊:用于產生空標志信號條件。其中rc1k、rst_n 和w2r_bincnt 分別是寫時鐘復位和寫計數器轉換到讀時鐘二進制計數器,設計代碼如下:

讀計數器同步寫時鐘域模塊:用于產生滿標志信號條件。其中wc1k 和rzw-bincnt 分別是寫時鐘和讀計數器轉換到寫時鐘二進制計數器,設計代碼如下:


空標志產生模塊:在讀使能有效的情況下,讀二進制計數器=寫格雷碼計數器同步并轉換到讀時鐘域的寫二進制計數器,empty=1,empty 信號產生具體代碼如下:

滿標志產生模塊:讀使能有效情況下,寫二進制值計數器計數到最大值且同步到寫時鐘域讀計數器計數最小值,或經同步后讀計數=寫計數器+1 時,full=1,full信號產生具體代碼如下:


針對異步FIFO 出現滿狀態的兩種情況進行兩次仿真:1)第一種情況,FIFO 一次寫滿,在讀時鐘和讀使能控制下依次向FIFO 寫入十進制5~20,16 個無符號數,最后一個寫操作結束,full=1,FIFO 寫滿。在寫時鐘和寫使能控制下依次從FIFO 讀出5~20,16個無符號數,最后一個讀操作結束,empty=1,FIFO 讀空,如圖6 所示;2)第二種情況,FIFO 多次寫滿,在讀時鐘和讀使能控制下依次向FIFO 寫入十進制1~16,16個無符號數,最后一個寫操作結束,full=1,FIFO 寫滿。在寫時鐘和寫使能控制下依次從FIFO 讀出1~10,10 個無符號數,再次向FIFO 寫入0~9,10 個無符號數,full=1,FIFO 寫滿,最后把FIFO11~16,0~9,16個數據依次讀出,empty=1,FIFO 讀空,如圖7 所示。

圖6 第一種寫滿情況

圖7 第二種寫滿情況
該文分析異步FIFO 內部結構,在此基礎之上深入分析異步電路亞穩態產生的原因,針對亞穩態原因提出采用同步器和格雷碼計數器的方法,可以有效降低亞穩態出現概率。針對傳統的空/滿標志位產生方法,提出一種新的空/滿標志位產生方法。使讀寫滿邏輯分兩種情況討論,分別對兩種情況進行Modelsim 仿真驗證,從仿真圖上看,該設計正確,實現了預期目標。