湘潭大學物理與光電工程學院 吳修英
湖南進芯電子科技有限公司 黃嵩人
信號的跨時鐘域傳輸很容易產生亞穩態,而亞穩態對于SOC的穩定運行又是潛在的巨大危險。異步信號的跨時鐘域處理又分為一位信號的同步和多位數據信號的同步。本文所研究的異步FIFO為多位數據信號的同步,主要作為不同時鐘域之間數據傳輸的中間緩存使用,大大降低了異步信號可能帶來的亞穩態[1]。FIFO是一種先入先出存儲器,沒有外部讀寫地址線,因此只能順序寫入和讀出,待寫入及讀出的數據位置由內部讀寫地址指針產生。
本項目所研發DSP采用改進型哈佛架構[2],集成有CPU及浮點處理器FPU。具有三組獨立的地址總線及三組獨立的數據總線。因此CPU對指令的讀取和對數據的操作可以同時進行,因此大大提高了CPU的運行速度,而flash、eeprom等非易失存儲器的存取速度遠低于CPU的運行速度,若是使用CPU直接和低速存儲器進行通信,則造成CPU的資源巨大浪費,為了匹配速度上的差別,為此特設計了異步FIFO模塊以實現速度的匹配。該DSP集成了I2C、SPI、PWM和EQEP等多種外設。
如圖1所示為異步FIFO的設計框圖。

圖1 異步FIFO工作原理圖
根據異步FIFO的工作原理,先定義出異步FIFO的主要端口信號及相關參數如下:
FIFO的深度:FIFO存儲體中所能容納的數據的總數。
FIFO的寬度:FIFO進行一次讀或者寫操作的數據位的位數。FIFO滿標志:滿標志位是由其狀態電路發出的指示信號,表示FIFO已滿或者將要滿,以阻止外部繼續對其進行寫操作而造成數據丟失。
FIFO空標志:空標志位是由其狀態電路發出的指示信號,表示FIFO已空或者將要空,以阻止外部繼續對其進行讀操作而造成讀出無效的數據。
讀數據時鐘rclk:讀操作所遵循的時鐘,在每個有效時鐘沿來臨時讀出數據。
寫數據時鐘wclk:寫操作所遵循的時鐘,在每個有效時鐘沿來臨時寫入數據。
讀數據指針rptr:指向下一個將要讀出的數據的地址,讀完后自動加1。
寫數據指針wptr:指向下一個將要寫入的數據的地址,寫入后自動加1。
異步FIFO的設計主要包括兩大模塊,一個是用于存儲數據的存儲體的設計,該存儲體一般使用代工廠提供的IP核;另一個是FIFO的讀寫控制器的設計。控制器主要是讀寫地址產生邏輯和空滿標志產生邏輯。
通過對讀指針和寫指針的比較,就可以產生FIFO空或者滿標志位。由于讀寫指針是屬于不同的時鐘域,而不同時鐘域之間直接比較會產生亞穩態的問題,因此要對其讀指針和寫指針進行比較的前提是將這兩個信號先同步到同一個時鐘域。在此設計中使用兩級D觸發器串聯來構成同步器,以對對這兩個信號進行同步[3]。
一般計數器的設計會采用二進制直接設計,這在同一個時鐘域里沒有什么大的問題,但對于跨時鐘域的設計采用二進制計數器則容易產生毛刺,而導致不穩定,因為二進制數從一個數值變換到另一個數值時可能多位數據位都會跳變,比如由1111到0000的跳變。而跳變的位數越多,在采樣時越容易產生錯誤。為了減小這種錯誤的發生,采用格雷碼對該計數器進行設計是一個很好的選擇,因為格雷碼在計數時由一個值跳變到下一個計數值時僅有一位發生跳變,這就大大降低了采樣錯誤的可能性。由于設計者大多習慣于二進制計數制,所以設計中采用二進制計數,但是要將二進制數再轉換為格雷碼以降低誤碼率。
根據二進制數與格雷碼之間的關系,可知二進制數到格雷碼轉換的公式為:
Gray =(bin[n-1:0])^{1’b0,bin[n-1:1]};
格雷碼到二進制數的轉換公式為:
bin[i] = ^(gray[n-1:i])
FIFO何時為空,何時為滿?對于FIFO的讀寫指針,總是指向下一個待讀出或者寫入的位置。約定在復位后讀寫指針同時回到初始位置,此時FIFO已經為空,只能對其進行寫人操作,寫入后如果再對其進行讀操作,如果讀時鐘大于寫時鐘,那么讀指針總會趕上寫指針。那么當讀指針等于寫指針的時候就認為FIFO已空,此時產生有效的空標志位。與之相比滿標志位的產生相對復雜些,如果寫指針已經指向FIFO的頂端并且此時還在繼續寫操作,則寫指針又回到FIFO的底部并開始向上增長,如果寫指針又“追趕上”了讀指針,則認為FIFO已滿。但是滿和空的條件都是讀寫指針指向FIFO同一位置[4]。究竟如何讓硬件判斷是滿還是空?為了區分兩種標志位,采用增加最高位地址位的辦法,低位地址用來作為指針對存儲體進行尋址,最高位作為空滿標志的判斷位。若是讀寫指針的低位相同且最高位也相同,則空標志位有效;若是讀寫指針的低位相同但最高位不同,則滿標志位有效。
該模塊采用兩級D觸發器的級連采樣同步,將格雷碼表示的讀指針同步到寫指針的時鐘域,采用兩級同步可以很好的消除亞穩態,對于頻率很高的設計,建議采用三級DFF同步采樣。采用同樣的設計方法亦可實現寫指針到讀指針的同步模塊wr_to_re的設計。Verilog設計主要部分代碼如下:

該模塊用來實現FIFO的讀控制,主要用來產生讀尋址指針、讀比較指針和二進制數到格雷碼的轉換。在設計中讀尋址指針比讀比較指針少一位,器設計原理見3.3節空滿標志位的產生。基于同樣的原理可設計出寫控制器模塊wr_ctrl。模塊verilog設計代碼如下:


根據上述對異步FIFO的理論分析及功能設計,采用業界流行的verilog語言對設計的模塊進行RTL級建模。對于驗證測試采用流行的EDA工具Synopsys公司的Ncverilog仿真工具,建立相應的Test bench,對所設計的異步FIFO的RTL級描述進行功能驗證[5]。仿真波形如圖2所示,對比仿真波形及功能需求可知,該異步FIFO的設計完全符合功能要求。該異步FIFO 成功應用于所研發的項目32位浮點型DSP中,實現了從外掛SPI Flash中緩存數據和程序,實現高速CPU和低速外設之間的速度匹配。其中的格雷碼使用也大大降低了產生亞穩態的可能性。
當wclk周期為100ns,rclk周期為200ns時,仿真波形如下:

當wclk周期為200ns,rclk周期為100ns時,仿真波形如下:

圖2 異步FIFO仿真波形圖
[1]李廣軍,林永生.Verilog HDL高級數字設計(第二版)[M].北京:電子工業出版社,2014.2:383-391.
[2]TMS320F28335 Digital Signal Controllers Data Manual.pdf[OL].2007.6:58-64.
[3]周潤德,等譯.數字集成電路—電路、系統與設計(第二版)[M].北京:電子工業出版社,2010.11:392-396.
[4]Simulation and Synthesis Techniques for Asynchronous FIFO design.pdf[OL].
[5]夏宇聞,楊雷,陳先勇等譯.SystemVerilog驗證方法學[M].北京:航空航天大學出版社,2007,5:173-187.