魏 珊,魏 豐,陳夢桐
(華中科技大學(xué) 人工智能與自動化學(xué)院,武漢 430074)
實(shí)現(xiàn)數(shù)據(jù)的暫存和雙向傳輸,一般會采用FIFO和雙口RAM這兩種模式作為數(shù)據(jù)交換和存儲的共享存儲器。FIFO(first input first output)是數(shù)據(jù)從一端先寫入然后在另一端優(yōu)先讀出來的存儲器,一般用于異步時(shí)鐘的數(shù)據(jù)交換系統(tǒng)中,充當(dāng)兩個(gè)不同時(shí)鐘系統(tǒng)間的數(shù)據(jù)暫存器。所以稱它為異步FIFO。雙口RAM是具有兩個(gè)端口的靜態(tài)存儲器,兩個(gè)端口分別有其自己的數(shù)據(jù)線,地址線和控制線,由于端口兩邊有獨(dú)立的總線,所以兩個(gè)CPU可以對雙口RAM同時(shí)進(jìn)行讀寫操作,或者一個(gè)CPU在一端對其讀操作,另一個(gè)CPU在另一端對其寫操作。雙口RAM的此特性實(shí)現(xiàn)了CPU之間數(shù)據(jù)的高效靈活交換。實(shí)驗(yàn)室的同步數(shù)據(jù)采集卡項(xiàng)目要求上位機(jī)可以根據(jù)需要對存儲器任意單元內(nèi)的數(shù)據(jù)進(jìn)行讀寫,這就對共享存儲器的讀寫方式有了一定的要求。FIFO存儲器的讀寫嚴(yán)格的按照先進(jìn)先出的規(guī)則,滿足不了該項(xiàng)目的需求。雙口RAM存儲器的讀寫是靈活的,可以根據(jù)需求清楚地了解到雙口RAM各個(gè)存儲單元的信息,正好符合此項(xiàng)目的要求,因此本文選擇雙口RAM作為該項(xiàng)目的共享存儲器[1]。
雙口RAM存儲器的實(shí)現(xiàn)既可以采用現(xiàn)成的雙口RAM芯片,也可以通過Verilog HDL語言在FPGA內(nèi)設(shè)計(jì)功能模塊,然后在Nios II開發(fā)環(huán)境中封裝成IP核來構(gòu)造完成?,F(xiàn)成的雙口RAM芯片有Integrated Device Technology公司研發(fā)的IDT7130,IDT7130是一種1K*8高速的雙端口的靜態(tài)RAM[2],RAM兩個(gè)端口的數(shù)據(jù),地址和控制線是獨(dú)立且對稱的,兩個(gè)CPU通過IDT7130內(nèi)部的硬件地址仲裁信號BUSY 信號可以從任一端口對IDT7130進(jìn)行完全異步的操作。此外IDT7130具有自動進(jìn)入低功耗狀態(tài)的特點(diǎn),因此IDT7130在民用和軍用上都很受歡迎。為了充分利用FPGA上現(xiàn)有的存儲器資源,同時(shí)簡化該項(xiàng)目硬件設(shè)計(jì)的復(fù)雜程度,本文采用通過對FPGA內(nèi)的存儲器進(jìn)行配置并將其封裝成IP核的形式來構(gòu)造雙口RAM。對其進(jìn)行功能測試后結(jié)果表明本文設(shè)計(jì)的雙口RAM實(shí)現(xiàn)了數(shù)字量和時(shí)標(biāo)信息在FPGA與PCI總線接口之間高速有效且不丟包的實(shí)時(shí)傳輸。
Altera公司為了提高主從設(shè)備之間數(shù)據(jù)交換效率和速率,開發(fā)了一種新的總線結(jié)構(gòu)Avalon總線。Avalon總線是Nios II處理器內(nèi)部模塊和外圍設(shè)備數(shù)據(jù)交換的一座橋梁,模塊之間通過Avalon總線連接形成片上可編程系統(tǒng)SOPC。Avalon總線的特點(diǎn)是采用了分離的地址、數(shù)據(jù)和控制總線,沒有信號選擇電路,大大簡化了數(shù)據(jù)傳輸?shù)膹?fù)雜性,提高了傳輸效率;Avalon總線上的信號是高低電平,這樣簡單的信號可以在總線上高效地傳輸[3]。PCI總線接口芯片CH365主要將高速復(fù)雜的PCI總線轉(zhuǎn)換成八位并行的數(shù)據(jù)線和地址線[4],上位機(jī)驅(qū)動程序通過總線接口芯片CH365對雙口RAM共享存儲器進(jìn)行讀寫。實(shí)現(xiàn)數(shù)據(jù)在FPGA和上位機(jī)之間雙向?qū)崟r(shí)地傳輸。圖1是Avalon總線和PCI總線接口芯片CH365通過共享存儲器雙口RAM進(jìn)行數(shù)交換示意圖。
圖1 PCI總線接口芯片CH365通過雙口RAM與Avalon總線通信
說明:PCI總線接口芯片CH365將復(fù)雜的PCI總線轉(zhuǎn)換為八位數(shù)據(jù)線和地址線,圖1可以看出接口芯片CH365對雙口RAM的讀寫操作的總線是公用的,Avalon總線的讀寫數(shù)據(jù)線則是分開的,為了充分使用FPGA現(xiàn)有的片上存儲器資源,本文在設(shè)計(jì)單時(shí)鐘真雙端口RAM的時(shí)候需要對CH365的數(shù)據(jù)線進(jìn)行一定的配置,使其符合FPGA自帶的存儲器的使用規(guī)則。這一特點(diǎn)也是設(shè)計(jì)雙口RAM的初衷之一和難點(diǎn)之一。由圖1可知整個(gè)系統(tǒng)只有一個(gè)時(shí)鐘clk,該時(shí)鐘來自于FPGA的系統(tǒng)時(shí)鐘,其作用是讓兩個(gè)CPU對雙口RAM有效有序的讀寫操作。rd_mem_by_ch365和Wr_mem_by_ch365分別是CH365對雙口RAM的讀寫使能信號。Write_enable是Avalon總線的對雙口RAM的寫使能信號。
圖2將FPGA內(nèi)的存儲器做了一個(gè)清晰的分類。
圖2 FPGA內(nèi)的存儲器
Altera公司開發(fā)的Cyclone IV EP4CE6E22C8N這款FPGA芯片具有嵌入式存儲器結(jié)構(gòu),這一特點(diǎn)滿足了該型號的FPGA對片上存儲器的需求。嵌入式存儲器的結(jié)構(gòu)由一系列M9K存儲器模塊構(gòu)成,對這些M9K存儲器模塊進(jìn)行一定的配置,即可以實(shí)現(xiàn)各種各樣的存儲器功能,例如RAM、移位寄存器、ROM以及FIFO緩沖器。M9K存儲器具有很多特性,例如存儲器的每一個(gè)端口都具有獨(dú)立的讀使能和寫使能信號,在Packed模式下,M9K存儲器模塊可被分成兩個(gè)4.5K單端口RAM,同時(shí)具有可變端口配置模式等。存儲器根據(jù)讀寫端口的個(gè)數(shù)可以被配置成簡單雙端口和真雙端口模式。
簡單雙端口模式: 這種模式下的存儲器一邊只有一個(gè)讀端口和另一邊只有一個(gè)寫端口,即這種模式支持不同位置的同時(shí)讀寫操作。
簡單雙端口RAM在讀的這一端口只有與讀相關(guān)的所有信號,例如讀地址信號wraddress[],讀使能信號wren,讀時(shí)鐘和讀使能時(shí)鐘。同理,在寫的這一端口只有與寫相關(guān)的所有信號。在此模式下,M9K存儲器模塊支持獨(dú)立讀寫使能信號rden和wren。在沒有進(jìn)行讀寫操作時(shí),一般講rden信號保持在低電平(無效狀態(tài)),從而降低功耗。相同地址上的Read-during-write操作能夠在相應(yīng)的位置上輸出“New Data”數(shù)據(jù),或者輸出“Old Data”數(shù)據(jù)。
圖3 簡單雙端口RAM
真雙端口模式:這種模式下的存儲器具有兩個(gè)獨(dú)立的寫端口和兩個(gè)獨(dú)立的讀端口,這種模式支持雙端口操作的任何組合,例如在兩個(gè)不同時(shí)鐘頻率上的兩個(gè)讀操作,兩個(gè)寫操作,或者一個(gè)端口的讀操作和另一個(gè)端口的寫操作[5]。
圖4 真雙端口RAM
相比于簡單雙端口模式,真雙端口模式下的RAM兩端口既有讀信號也有寫信號,因此在此模式下的RAM可以對存儲器某一端口任意獨(dú)立地進(jìn)行讀寫操作,而不是固定哪個(gè)端口只能讀或者只能寫操作。對于存儲器的操作更加靈活。當(dāng)存儲器兩個(gè)端口對存儲器同一位置進(jìn)行讀寫操作時(shí),可能會出現(xiàn)沖突,此時(shí)需要外部的沖裁電路來解決。
除此之外根據(jù)雙端口RAM的時(shí)鐘個(gè)數(shù)又可以細(xì)分為單時(shí)鐘簡單雙端口RAM、雙時(shí)鐘簡單雙端口RAM、單時(shí)鐘真雙端口RAM和雙時(shí)鐘真雙口RAM。時(shí)鐘是一個(gè)系統(tǒng)的脈搏,在所有系統(tǒng)中扮演著非常重要的角色,系統(tǒng)有條不紊的運(yùn)行離不開時(shí)鐘。存儲器也一樣,對存儲器進(jìn)行正確地讀寫操作離不開時(shí)標(biāo)信號。觀察IDT7130雙端口靜態(tài)RAM芯片的讀寫時(shí)序圖,我們發(fā)現(xiàn)IDT7130芯片沒有時(shí)鐘信號,仔細(xì)閱讀它的內(nèi)部功能電路你會發(fā)現(xiàn)有I/O控制單元,地址譯碼器,存儲器陣列以及仲裁邏輯控制的電路,在這些電路的基礎(chǔ)上IDT7130采用中斷方式交換信令的方法以及有效操作BUSY信號獲得時(shí)標(biāo)信號,從而對其進(jìn)行高效有序的讀寫。FPGA內(nèi)部的存儲器是直接采用時(shí)鐘信號的形式來完成對存儲器正確有序的讀寫操作,時(shí)鐘信號控制著操作的先后次序,達(dá)到了數(shù)據(jù)交換的準(zhǔn)確性和高效性。
根據(jù)圖1,該項(xiàng)目中的雙端口共享存儲器RAM只有一個(gè)時(shí)鐘?;谠擁?xiàng)目的需求,本文主要設(shè)計(jì)的是只有一個(gè)時(shí)鐘的真雙端口RAM。
本文采用自上而下的設(shè)計(jì)思想設(shè)計(jì)了共享存儲器雙口RAM[6]。選擇用Altera公司研發(fā)的的Cyclone IV E系列EP4CE6E22C8N FPGA器件,該系列器件具有6K的邏輯單元、270 Kbits的嵌入式存儲器、2個(gè)通用的PLL,最大用戶I/O可以達(dá)到179個(gè)、其中Nios II的最高頻率可以達(dá)到170 MHz。該器件具有低成本高性價(jià)比的特性,被廣泛使用。本文在這款FPGA器件內(nèi)實(shí)現(xiàn)了256字節(jié)存儲容量的單時(shí)鐘真雙端口RAM共享存儲器。主要通過Verilog HDL語言來進(jìn)行設(shè)計(jì)。首先我們選擇的硬件開發(fā)環(huán)境是QuartusII第11.0(64位)版本,該軟件主要通過硬件描述語言Verilog HDL實(shí)現(xiàn)FPGA的資源的分配利用[7],Verilog HDL編寫.V文件,然后對其編譯、綜合,最后下載到FPGA內(nèi)即可實(shí)現(xiàn)對FPGA資源的使用。該開發(fā)環(huán)境還可以對所設(shè)計(jì)的模型的時(shí)序進(jìn)行分析,從而檢測該模型是否符合設(shè)計(jì)需求[8]。選擇NiosII的第11.0版本為軟件開發(fā)環(huán)境。SOPC的配置文件(后綴名.sopcinfo)是連接軟件和硬件資源的重要文件[9]。在開發(fā)環(huán)境QuartusII內(nèi)部其實(shí)有很多FPGA內(nèi)部資源的例程代碼供參考,本文開發(fā)的單時(shí)鐘真雙端口RAM就是參考QuartusII內(nèi)部的RAM例程來完成的。
本文采用模塊化的程序設(shè)計(jì),設(shè)計(jì)了兩個(gè)模塊,即兩個(gè).V文件。一個(gè)是QuartusII內(nèi)部的單時(shí)鐘真雙端口RAM文件,另一個(gè)是根據(jù)項(xiàng)目中共享存儲器兩端口總線的特點(diǎn)設(shè)計(jì)了一個(gè)將Avalon總線和CH365接口總線連接起來的文件。對于第一個(gè)文件首先將QuartusII內(nèi)部的單時(shí)鐘真雙端口RAM例程調(diào)出來,然后對其修改,具體步驟是:在QuartusII開發(fā)環(huán)境中新建一個(gè)Verilog HDL File文件,回到主界面點(diǎn)擊菜單欄中的Edit下拉菜單中有一項(xiàng)是Insert Template,出現(xiàn)的對話框有語言例程的分類,包括AHDL語言、VHDL語言和Verilog HDL語言等,本文選擇Verilog HDL,里面包括Full Design、Logic、Synthesis Attributes等,本文選擇Full Design,內(nèi)部包括RAMs and ROMs,選中會發(fā)現(xiàn)有很多例程,根據(jù)本項(xiàng)目需求選擇True Dual Port RAM(single clock),將其例程代碼導(dǎo)入到最初建立的Verilog HDL File文件中,對其做了一點(diǎn)修改,這樣單時(shí)鐘真雙端口RAM的內(nèi)部基本結(jié)構(gòu)獲得了,但是該基本結(jié)構(gòu)缺少端口信號的具體設(shè)計(jì)。聯(lián)系實(shí)際情況本文設(shè)計(jì)了第二個(gè)Verilog HDL File文件。
圖5 QuartusⅡ內(nèi)部的單時(shí)鐘真雙端口RAM例程
在對第二個(gè).V文件設(shè)計(jì)的時(shí)候,考慮到FPGA中的SOPC系統(tǒng)各個(gè)模塊之間數(shù)據(jù)交換的總線標(biāo)準(zhǔn)是Avalon總線,本文設(shè)計(jì)的單時(shí)鐘真雙端口RAM最終要嵌入進(jìn)SOPC系統(tǒng)中,而CH365接口總線的讀寫數(shù)據(jù)線和Avalon總線的讀寫數(shù)據(jù)線存在差異,CH365接口總線的讀寫操作公用一條數(shù)據(jù)總線,Avalon總線具有單獨(dú)的讀數(shù)據(jù)線和單獨(dú)的些數(shù)據(jù)線。考慮到這一點(diǎn),我們來設(shè)計(jì)第二個(gè).V文件[10],主要解決第一個(gè).V文件沒有解決的問題以及配置CH365接口的讀寫數(shù)據(jù)總線。首先配置第一個(gè).V文件定義的雙口RAM的各個(gè)端口信號,主要包括系統(tǒng)時(shí)鐘信號clk,兩端地址總線,數(shù)據(jù)總線的定義和讀寫使能信號的定義。然后合并CH365接口總線這邊的數(shù)據(jù)線,實(shí)現(xiàn)的方法是程序中自定義了一個(gè)CH365數(shù)據(jù)總線輸入輸出控制信號dir_ch365,在系統(tǒng)時(shí)鐘有效地前提下,當(dāng)365的寫雙口RAM的寫使能信號有效的時(shí)候控制信號dir_ch365置1,此時(shí)CH365的數(shù)據(jù)總線作為輸出,向雙口RAM寫數(shù)據(jù)。反之,在系統(tǒng)時(shí)鐘有效的前提下,當(dāng)365的讀雙口RAM的讀使能信號有效的時(shí)候控制信號dir_ch365置0,此時(shí)數(shù)據(jù)CH365的數(shù)據(jù)總線作為輸入,讀取雙口RAM中的數(shù)據(jù)。
圖6 CH365接口數(shù)據(jù)總線處理部分代碼
將自定基于Avalon總線的單時(shí)鐘真雙端口RAM模塊封裝成IP核嵌入到SOPC系統(tǒng)中需要在工具SOPC Builder中完成。首先在菜單欄Project中新建自定義組件點(diǎn)擊New component,出現(xiàn)圖7的對話框。首先是組件編輯(component editor)的簡介。第二步硬件描述語言文件(HDL Files)的加載,之前寫好的兩個(gè).V文件就是要從這里加載進(jìn)去,加載的同時(shí)系統(tǒng)會自動編譯。第三步.V文件中自定義的端口信號與雙口RAM內(nèi)部信號之間一一對應(yīng)的配置了,主要包括信號類型、信號寬度以及信號的方向。第四步信號線參數(shù)以及時(shí)序的配置。第五步數(shù)據(jù)總線和地址總線位寬的配置,數(shù)據(jù)總線和地址總線本在設(shè)計(jì)的都是8位。最后給配置完的IP核和命名,以及它屬于的IP核組,方便使用者找到并使用。點(diǎn)擊Finish后,系統(tǒng)首先進(jìn)行編譯最后生成自定義的IP核組件。這個(gè)IP核可以供使用者使用,同時(shí)還可以根據(jù)設(shè)計(jì)者的需求對其進(jìn)行修改,方便靈活。
圖7 單時(shí)鐘真雙端口RAM
前文說過,雙口RAM作為數(shù)據(jù)交換的共享存儲器也有其不足之處。當(dāng)兩端的系統(tǒng)同時(shí)對雙口RAM的同一單元讀數(shù)據(jù)或者寫數(shù)據(jù)的時(shí)候,會出現(xiàn)錯(cuò)讀的現(xiàn)象,讀到的數(shù)據(jù)不是使用者所需要的數(shù)據(jù)。針對這一現(xiàn)象,本文采用奇偶交換頁的思想來訪問雙口RAM。雙口RAM的每16個(gè)字節(jié)單元為一頁,分為奇數(shù)頁和偶數(shù)頁,偶數(shù)頁作為雙口RAM的起始頁[1]。當(dāng)某一系統(tǒng)往奇數(shù)頁寫完或者讀完數(shù)據(jù)后,將奇數(shù)頁的標(biāo)志位置1。當(dāng)系統(tǒng)操作完偶數(shù)頁時(shí),偶數(shù)頁的標(biāo)志位置0。系統(tǒng)再次訪問這些單元的時(shí)候先訪問奇偶標(biāo)志位,判斷完成以后再訪問存儲單元里面的數(shù)據(jù)。這樣的訪問存儲單元的思想有效地避免了數(shù)據(jù)錯(cuò)讀的顯小,提高了雙口RAM雙向通信的效率。
為了驗(yàn)證本文設(shè)計(jì)的單時(shí)鐘真雙端口RAM的正確與否,本文首先在硬件開發(fā)環(huán)境QuartusII 11.0中設(shè)計(jì)設(shè)計(jì)硬件原理圖構(gòu)成SOPC硬件系統(tǒng),然后在軟件開發(fā)環(huán)境NiosII 11.0中編寫測試雙口RAM的代碼。方法是向已經(jīng)嵌入到SOPC中的雙口RAM寫入簡單的數(shù)據(jù),然后讀出雙口RAM中的數(shù)據(jù),最終在顯示終端打印出來。其測試結(jié)果如圖8所示。為了驗(yàn)證本文設(shè)計(jì)的雙口RAM是否可以通過PCI總線和上位機(jī)進(jìn)行數(shù)據(jù)交換,本文還在LINUX環(huán)境下建立PCI字符設(shè)備,對所建立的PCI字符設(shè)備讀寫操作,測試雙口RAM的功能,其測試結(jié)果如圖9所示。最后在NiosII中編寫軟件將項(xiàng)目中設(shè)計(jì)的同步時(shí)鐘采集卡通過CPS接收機(jī)采集到的時(shí)標(biāo)信息傳送到臺式機(jī),測試雙口RAM能否在FPGA和上位機(jī)之間實(shí)現(xiàn)數(shù)據(jù)正確高效的雙向傳輸。其結(jié)果如圖9所示。
圖8 雙口RAM與NiosII之間的通信測試結(jié)果
說明:圖8的結(jié)果顯示了數(shù)據(jù)可以正確地在雙口RAM和NiosII之前傳輸,說明本文所設(shè)計(jì)的單時(shí)鐘真雙端口RAM是可用的。圖9的結(jié)果表明本文所設(shè)計(jì)的單時(shí)鐘真雙端口RAM 可以通過PCI總線和上位機(jī)有效通信。圖10是GPS接收機(jī)接收到的時(shí)標(biāo)信息通過NiosII處理器處理之后的信息,NiosII處理器將其存放在本文所設(shè)計(jì)的雙口RAM中,上位機(jī)在LINUX操作系統(tǒng)中將雙口RAM中的數(shù)據(jù)讀取出來,然后在上位機(jī)上顯示的結(jié)果,此結(jié)果證明了FPGA和計(jì)算機(jī)的通信是可行的,本文所設(shè)計(jì)的單時(shí)鐘真雙端口RAM是成功的。
圖9 雙口RAM與上位機(jī)之間的通信測試結(jié)果
圖10 NiosII通過雙口RAM與上位機(jī)之間通信測試結(jié)果
共享存儲器作為數(shù)據(jù)交換的橋梁,在數(shù)據(jù)通信系統(tǒng)中起著至關(guān)重要的作用,在圖像處理等數(shù)據(jù)量比較大的領(lǐng)域,實(shí)現(xiàn)數(shù)據(jù)高效實(shí)時(shí)地傳輸是一個(gè)難點(diǎn),也是一個(gè)重點(diǎn),為了緩解數(shù)據(jù)傳輸?shù)膲毫7],數(shù)據(jù)共享存儲器獲得了越來越多的青睞。本文以GPS同步數(shù)據(jù)采集卡項(xiàng)目為應(yīng)用實(shí)例,充分利用現(xiàn)場可編程門陣列FPGA的片上存儲器的資源,成功地開發(fā)了基于Avalon總線的單時(shí)鐘真雙端口模式的RAM共享存儲器,本文所設(shè)計(jì)的雙口RAM存儲容量有256字節(jié),由于PCI總線接口芯片的數(shù)據(jù)和地址都是固定的8位,本文設(shè)計(jì)的雙口RAM固定了數(shù)據(jù)線和地址線為8位。為了避免數(shù)據(jù)在高速傳輸?shù)臅r(shí)候出現(xiàn)丟包現(xiàn)象,本文提出了奇偶頁交換數(shù)據(jù)的思想,由于要傳輸?shù)膱?bào)文信息的長度是12字節(jié),本文以16字節(jié)為一頁,分為奇偶頁,數(shù)據(jù)輪流交換。實(shí)現(xiàn)了12字節(jié)報(bào)文信息在FPGA和上位機(jī)之間高效且不丟包的實(shí)時(shí)傳輸。