魏 珊,魏 豐,陳夢桐
(華中科技大學 人工智能與自動化學院,武漢 430074)
實現數據的暫存和雙向傳輸,一般會采用FIFO和雙口RAM這兩種模式作為數據交換和存儲的共享存儲器。FIFO(first input first output)是數據從一端先寫入然后在另一端優先讀出來的存儲器,一般用于異步時鐘的數據交換系統中,充當兩個不同時鐘系統間的數據暫存器。所以稱它為異步FIFO。雙口RAM是具有兩個端口的靜態存儲器,兩個端口分別有其自己的數據線,地址線和控制線,由于端口兩邊有獨立的總線,所以兩個CPU可以對雙口RAM同時進行讀寫操作,或者一個CPU在一端對其讀操作,另一個CPU在另一端對其寫操作。雙口RAM的此特性實現了CPU之間數據的高效靈活交換。實驗室的同步數據采集卡項目要求上位機可以根據需要對存儲器任意單元內的數據進行讀寫,這就對共享存儲器的讀寫方式有了一定的要求。FIFO存儲器的讀寫嚴格的按照先進先出的規則,滿足不了該項目的需求。雙口RAM存儲器的讀寫是靈活的,可以根據需求清楚地了解到雙口RAM各個存儲單元的信息,正好符合此項目的要求,因此本文選擇雙口RAM作為該項目的共享存儲器[1]。
雙口RAM存儲器的實現既可以采用現成的雙口RAM芯片,也可以通過Verilog HDL語言在FPGA內設計功能模塊,然后在Nios II開發環境中封裝成IP核來構造完成?,F成的雙口RAM芯片有Integrated Device Technology公司研發的IDT7130,IDT7130是一種1K*8高速的雙端口的靜態RAM[2],RAM兩個端口的數據,地址和控制線是獨立且對稱的,兩個CPU通過IDT7130內部的硬件地址仲裁信號BUSY 信號可以從任一端口對IDT7130進行完全異步的操作。此外IDT7130具有自動進入低功耗狀態的特點,因此IDT7130在民用和軍用上都很受歡迎。為了充分利用FPGA上現有的存儲器資源,同時簡化該項目硬件設計的復雜程度,本文采用通過對FPGA內的存儲器進行配置并將其封裝成IP核的形式來構造雙口RAM。對其進行功能測試后結果表明本文設計的雙口RAM實現了數字量和時標信息在FPGA與PCI總線接口之間高速有效且不丟包的實時傳輸。
Altera公司為了提高主從設備之間數據交換效率和速率,開發了一種新的總線結構Avalon總線。Avalon總線是Nios II處理器內部模塊和外圍設備數據交換的一座橋梁,模塊之間通過Avalon總線連接形成片上可編程系統SOPC。Avalon總線的特點是采用了分離的地址、數據和控制總線,沒有信號選擇電路,大大簡化了數據傳輸的復雜性,提高了傳輸效率;Avalon總線上的信號是高低電平,這樣簡單的信號可以在總線上高效地傳輸[3]。PCI總線接口芯片CH365主要將高速復雜的PCI總線轉換成八位并行的數據線和地址線[4],上位機驅動程序通過總線接口芯片CH365對雙口RAM共享存儲器進行讀寫。實現數據在FPGA和上位機之間雙向實時地傳輸。圖1是Avalon總線和PCI總線接口芯片CH365通過共享存儲器雙口RAM進行數交換示意圖。

圖1 PCI總線接口芯片CH365通過雙口RAM與Avalon總線通信
說明:PCI總線接口芯片CH365將復雜的PCI總線轉換為八位數據線和地址線,圖1可以看出接口芯片CH365對雙口RAM的讀寫操作的總線是公用的,Avalon總線的讀寫數據線則是分開的,為了充分使用FPGA現有的片上存儲器資源,本文在設計單時鐘真雙端口RAM的時候需要對CH365的數據線進行一定的配置,使其符合FPGA自帶的存儲器的使用規則。這一特點也是設計雙口RAM的初衷之一和難點之一。由圖1可知整個系統只有一個時鐘clk,該時鐘來自于FPGA的系統時鐘,其作用是讓兩個CPU對雙口RAM有效有序的讀寫操作。rd_mem_by_ch365和Wr_mem_by_ch365分別是CH365對雙口RAM的讀寫使能信號。Write_enable是Avalon總線的對雙口RAM的寫使能信號。
圖2將FPGA內的存儲器做了一個清晰的分類。

圖2 FPGA內的存儲器
Altera公司開發的Cyclone IV EP4CE6E22C8N這款FPGA芯片具有嵌入式存儲器結構,這一特點滿足了該型號的FPGA對片上存儲器的需求。嵌入式存儲器的結構由一系列M9K存儲器模塊構成,對這些M9K存儲器模塊進行一定的配置,即可以實現各種各樣的存儲器功能,例如RAM、移位寄存器、ROM以及FIFO緩沖器。M9K存儲器具有很多特性,例如存儲器的每一個端口都具有獨立的讀使能和寫使能信號,在Packed模式下,M9K存儲器模塊可被分成兩個4.5K單端口RAM,同時具有可變端口配置模式等。存儲器根據讀寫端口的個數可以被配置成簡單雙端口和真雙端口模式。
簡單雙端口模式: 這種模式下的存儲器一邊只有一個讀端口和另一邊只有一個寫端口,即這種模式支持不同位置的同時讀寫操作。
簡單雙端口RAM在讀的這一端口只有與讀相關的所有信號,例如讀地址信號wraddress[],讀使能信號wren,讀時鐘和讀使能時鐘。同理,在寫的這一端口只有與寫相關的所有信號。在此模式下,M9K存儲器模塊支持獨立讀寫使能信號rden和wren。在沒有進行讀寫操作時,一般講rden信號保持在低電平(無效狀態),從而降低功耗。相同地址上的Read-during-write操作能夠在相應的位置上輸出“New Data”數據,或者輸出“Old Data”數據。

圖3 簡單雙端口RAM
真雙端口模式:這種模式下的存儲器具有兩個獨立的寫端口和兩個獨立的讀端口,這種模式支持雙端口操作的任何組合,例如在兩個不同時鐘頻率上的兩個讀操作,兩個寫操作,或者一個端口的讀操作和另一個端口的寫操作[5]。

圖4 真雙端口RAM
相比于簡單雙端口模式,真雙端口模式下的RAM兩端口既有讀信號也有寫信號,因此在此模式下的RAM可以對存儲器某一端口任意獨立地進行讀寫操作,而不是固定哪個端口只能讀或者只能寫操作。對于存儲器的操作更加靈活。當存儲器兩個端口對存儲器同一位置進行讀寫操作時,可能會出現沖突,此時需要外部的沖裁電路來解決。
除此之外根據雙端口RAM的時鐘個數又可以細分為單時鐘簡單雙端口RAM、雙時鐘簡單雙端口RAM、單時鐘真雙端口RAM和雙時鐘真雙口RAM。時鐘是一個系統的脈搏,在所有系統中扮演著非常重要的角色,系統有條不紊的運行離不開時鐘。存儲器也一樣,對存儲器進行正確地讀寫操作離不開時標信號。觀察IDT7130雙端口靜態RAM芯片的讀寫時序圖,我們發現IDT7130芯片沒有時鐘信號,仔細閱讀它的內部功能電路你會發現有I/O控制單元,地址譯碼器,存儲器陣列以及仲裁邏輯控制的電路,在這些電路的基礎上IDT7130采用中斷方式交換信令的方法以及有效操作BUSY信號獲得時標信號,從而對其進行高效有序的讀寫。FPGA內部的存儲器是直接采用時鐘信號的形式來完成對存儲器正確有序的讀寫操作,時鐘信號控制著操作的先后次序,達到了數據交換的準確性和高效性。
根據圖1,該項目中的雙端口共享存儲器RAM只有一個時鐘。基于該項目的需求,本文主要設計的是只有一個時鐘的真雙端口RAM。
本文采用自上而下的設計思想設計了共享存儲器雙口RAM[6]。選擇用Altera公司研發的的Cyclone IV E系列EP4CE6E22C8N FPGA器件,該系列器件具有6K的邏輯單元、270 Kbits的嵌入式存儲器、2個通用的PLL,最大用戶I/O可以達到179個、其中Nios II的最高頻率可以達到170 MHz。該器件具有低成本高性價比的特性,被廣泛使用。本文在這款FPGA器件內實現了256字節存儲容量的單時鐘真雙端口RAM共享存儲器。主要通過Verilog HDL語言來進行設計。首先我們選擇的硬件開發環境是QuartusII第11.0(64位)版本,該軟件主要通過硬件描述語言Verilog HDL實現FPGA的資源的分配利用[7],Verilog HDL編寫.V文件,然后對其編譯、綜合,最后下載到FPGA內即可實現對FPGA資源的使用。該開發環境還可以對所設計的模型的時序進行分析,從而檢測該模型是否符合設計需求[8]。選擇NiosII的第11.0版本為軟件開發環境。SOPC的配置文件(后綴名.sopcinfo)是連接軟件和硬件資源的重要文件[9]。在開發環境QuartusII內部其實有很多FPGA內部資源的例程代碼供參考,本文開發的單時鐘真雙端口RAM就是參考QuartusII內部的RAM例程來完成的。
本文采用模塊化的程序設計,設計了兩個模塊,即兩個.V文件。一個是QuartusII內部的單時鐘真雙端口RAM文件,另一個是根據項目中共享存儲器兩端口總線的特點設計了一個將Avalon總線和CH365接口總線連接起來的文件。對于第一個文件首先將QuartusII內部的單時鐘真雙端口RAM例程調出來,然后對其修改,具體步驟是:在QuartusII開發環境中新建一個Verilog HDL File文件,回到主界面點擊菜單欄中的Edit下拉菜單中有一項是Insert Template,出現的對話框有語言例程的分類,包括AHDL語言、VHDL語言和Verilog HDL語言等,本文選擇Verilog HDL,里面包括Full Design、Logic、Synthesis Attributes等,本文選擇Full Design,內部包括RAMs and ROMs,選中會發現有很多例程,根據本項目需求選擇True Dual Port RAM(single clock),將其例程代碼導入到最初建立的Verilog HDL File文件中,對其做了一點修改,這樣單時鐘真雙端口RAM的內部基本結構獲得了,但是該基本結構缺少端口信號的具體設計。聯系實際情況本文設計了第二個Verilog HDL File文件。

圖5 QuartusⅡ內部的單時鐘真雙端口RAM例程
在對第二個.V文件設計的時候,考慮到FPGA中的SOPC系統各個模塊之間數據交換的總線標準是Avalon總線,本文設計的單時鐘真雙端口RAM最終要嵌入進SOPC系統中,而CH365接口總線的讀寫數據線和Avalon總線的讀寫數據線存在差異,CH365接口總線的讀寫操作公用一條數據總線,Avalon總線具有單獨的讀數據線和單獨的些數據線。考慮到這一點,我們來設計第二個.V文件[10],主要解決第一個.V文件沒有解決的問題以及配置CH365接口的讀寫數據總線。首先配置第一個.V文件定義的雙口RAM的各個端口信號,主要包括系統時鐘信號clk,兩端地址總線,數據總線的定義和讀寫使能信號的定義。然后合并CH365接口總線這邊的數據線,實現的方法是程序中自定義了一個CH365數據總線輸入輸出控制信號dir_ch365,在系統時鐘有效地前提下,當365的寫雙口RAM的寫使能信號有效的時候控制信號dir_ch365置1,此時CH365的數據總線作為輸出,向雙口RAM寫數據。反之,在系統時鐘有效的前提下,當365的讀雙口RAM的讀使能信號有效的時候控制信號dir_ch365置0,此時數據CH365的數據總線作為輸入,讀取雙口RAM中的數據。

圖6 CH365接口數據總線處理部分代碼
將自定基于Avalon總線的單時鐘真雙端口RAM模塊封裝成IP核嵌入到SOPC系統中需要在工具SOPC Builder中完成。首先在菜單欄Project中新建自定義組件點擊New component,出現圖7的對話框。首先是組件編輯(component editor)的簡介。第二步硬件描述語言文件(HDL Files)的加載,之前寫好的兩個.V文件就是要從這里加載進去,加載的同時系統會自動編譯。第三步.V文件中自定義的端口信號與雙口RAM內部信號之間一一對應的配置了,主要包括信號類型、信號寬度以及信號的方向。第四步信號線參數以及時序的配置。第五步數據總線和地址總線位寬的配置,數據總線和地址總線本在設計的都是8位。最后給配置完的IP核和命名,以及它屬于的IP核組,方便使用者找到并使用。點擊Finish后,系統首先進行編譯最后生成自定義的IP核組件。這個IP核可以供使用者使用,同時還可以根據設計者的需求對其進行修改,方便靈活。

圖7 單時鐘真雙端口RAM
前文說過,雙口RAM作為數據交換的共享存儲器也有其不足之處。當兩端的系統同時對雙口RAM的同一單元讀數據或者寫數據的時候,會出現錯讀的現象,讀到的數據不是使用者所需要的數據。針對這一現象,本文采用奇偶交換頁的思想來訪問雙口RAM。雙口RAM的每16個字節單元為一頁,分為奇數頁和偶數頁,偶數頁作為雙口RAM的起始頁[1]。當某一系統往奇數頁寫完或者讀完數據后,將奇數頁的標志位置1。當系統操作完偶數頁時,偶數頁的標志位置0。系統再次訪問這些單元的時候先訪問奇偶標志位,判斷完成以后再訪問存儲單元里面的數據。這樣的訪問存儲單元的思想有效地避免了數據錯讀的顯小,提高了雙口RAM雙向通信的效率。
為了驗證本文設計的單時鐘真雙端口RAM的正確與否,本文首先在硬件開發環境QuartusII 11.0中設計設計硬件原理圖構成SOPC硬件系統,然后在軟件開發環境NiosII 11.0中編寫測試雙口RAM的代碼。方法是向已經嵌入到SOPC中的雙口RAM寫入簡單的數據,然后讀出雙口RAM中的數據,最終在顯示終端打印出來。其測試結果如圖8所示。為了驗證本文設計的雙口RAM是否可以通過PCI總線和上位機進行數據交換,本文還在LINUX環境下建立PCI字符設備,對所建立的PCI字符設備讀寫操作,測試雙口RAM的功能,其測試結果如圖9所示。最后在NiosII中編寫軟件將項目中設計的同步時鐘采集卡通過CPS接收機采集到的時標信息傳送到臺式機,測試雙口RAM能否在FPGA和上位機之間實現數據正確高效的雙向傳輸。其結果如圖9所示。

圖8 雙口RAM與NiosII之間的通信測試結果
說明:圖8的結果顯示了數據可以正確地在雙口RAM和NiosII之前傳輸,說明本文所設計的單時鐘真雙端口RAM是可用的。圖9的結果表明本文所設計的單時鐘真雙端口RAM 可以通過PCI總線和上位機有效通信。圖10是GPS接收機接收到的時標信息通過NiosII處理器處理之后的信息,NiosII處理器將其存放在本文所設計的雙口RAM中,上位機在LINUX操作系統中將雙口RAM中的數據讀取出來,然后在上位機上顯示的結果,此結果證明了FPGA和計算機的通信是可行的,本文所設計的單時鐘真雙端口RAM是成功的。

圖9 雙口RAM與上位機之間的通信測試結果

圖10 NiosII通過雙口RAM與上位機之間通信測試結果
共享存儲器作為數據交換的橋梁,在數據通信系統中起著至關重要的作用,在圖像處理等數據量比較大的領域,實現數據高效實時地傳輸是一個難點,也是一個重點,為了緩解數據傳輸的壓力[7],數據共享存儲器獲得了越來越多的青睞。本文以GPS同步數據采集卡項目為應用實例,充分利用現場可編程門陣列FPGA的片上存儲器的資源,成功地開發了基于Avalon總線的單時鐘真雙端口模式的RAM共享存儲器,本文所設計的雙口RAM存儲容量有256字節,由于PCI總線接口芯片的數據和地址都是固定的8位,本文設計的雙口RAM固定了數據線和地址線為8位。為了避免數據在高速傳輸的時候出現丟包現象,本文提出了奇偶頁交換數據的思想,由于要傳輸的報文信息的長度是12字節,本文以16字節為一頁,分為奇偶頁,數據輪流交換。實現了12字節報文信息在FPGA和上位機之間高效且不丟包的實時傳輸。