基于NiosII的SOPC多處理器系統設計方法
摘要 詳細地闡述基于NiosIl和FPGA的多處理器系統的實(shí)現機制,討論利用硬件互斥核實(shí)現多處理器資源共享的方法,并給出硬件設計的具體步驟以及軟件設計、調試方法和關(guān)鍵技術(shù);利用Altera公司提供的QuartusII、SOPC Builder和NiosII IDE等開(kāi)發(fā)工具,通過(guò)一個(gè)3處理器系統設計實(shí)例,驗證了設計方法的正確性,實(shí)現了3處理器對存儲器資源的共享。
本文引用地址:http://dyxdggzs.com/article/79808.htm關(guān)鍵詞 SOPC NiosII 多處理器系統 共享存儲器
兩個(gè)或多個(gè)微處理器一起工作來(lái)完成某個(gè)任務(wù)的系統稱(chēng)為“多處理器系統”。傳統基于單片機的多處理器系統結構復雜,可靠性差;而基于32位的嵌入式軟核處理器NiosII的SOPC(可編程片上系統)多處理器系統解決方案,從根本上改變了多處理器系統的設計理念和方法。使用Altera公司的NiosII軟核處理器和SOPC Builder工具,可以快速地設計和建立共享資源的多處理器系統。多處理器系統一般用于工作站和使用分載(load-sharing)的復雜算法(稱(chēng)為“對稱(chēng)多處理器SMP”)的高端PC計算。對于大部分嵌入式系統,當SMP的開(kāi)銷(xiāo)太大時(shí),使用多個(gè)處理器執行不同的任務(wù),實(shí)現不同的功能正引起越來(lái)越多的關(guān)注。Altera公司的FPGA為開(kāi)發(fā)非對稱(chēng)的嵌入式多處理器系統提供了一個(gè)理想的平臺。為了提供理想的系統性能,使用SOPC Builder工具可以很容易地對硬件進(jìn)行修改和調整,從而很快完成不同配置系統的沒(méi)計、編譯和評估。
本文將對基于NiosII的OSPC多處理器系統的實(shí)現原理、設計流程和方法進(jìn)行詳細的討論。
1 NiosII多處理器系統硬件設計
QuartusII 5.O及以上版本支持多處理器系統的創(chuàng )建和調試。多個(gè)NiosII處理器能夠有效地共享系統資源。由于SOPC Builder允許用戶(hù)輕松添加多個(gè)處理器到系統中,因此建立多處理器系統的難點(diǎn)已不再是硬件的排列和連接,而在于多個(gè)處理器的軟件設計,使它們正常操作,相互之間不產(chǎn)生沖突。NiosII多處理器系統分為2類(lèi):一類(lèi)是共享資源的多處理器系統;另一類(lèi)處理器相互獨立,之間不進(jìn)行信息交換。
2 NiosII多處理器系統的資源共享
資源共享是多處理器系統的強大功能,但必須仔細考慮所要共享的資源,以及不同處理器如何使用共享資源。
2.1 共享存儲器
在多處理器系統中最普遍的共享資源是存儲器。共享存儲器用于存放任何數據,從指示處理器間通信狀態(tài)的簡(jiǎn)單標志,到被多個(gè)處理器同時(shí)進(jìn)行計算的復雜數據結構。
如果存儲器中包含不只一個(gè)處理器的程序代碼,那么每個(gè)處理器需要有不同的存儲地址。對于程序空間,處理器不能共享存儲器的同一區域。如果共享數據存儲器,則存儲器的數據需要從端口與共享存儲器的處理器的數據主端口連接。多處理器之問(wèn)共享數據存儲器比共享指令存儲器困難,原因是數據存儲器可讀/寫(xiě)。如果某一處理器正在對共享存儲器的特定區域進(jìn)行寫(xiě)操作,而同時(shí)另一個(gè)處理器正在對同一區域進(jìn)行讀或寫(xiě)操作,則很可能出現數據錯誤,至少使應用程序出錯,甚至使系統崩潰。
共享存儲器的處理器需要一個(gè)機制來(lái)通知其他處理器何時(shí)正在使用共享資源,以便不受其他處理器的干擾。
2.2 硬件互斥核
NiosII處理器允許使用其硬件互斥核部件對共享資源進(jìn)行保護處理。這個(gè)硬件互斥核不是一個(gè)NiosII處理器內部的部件,而是一個(gè)稱(chēng)為Mutex的SOPC Builder組件。
互斥核也可看作一種共享資源,提供一個(gè)原子的“測試和置位”操作,處理器測試Mutex是否可行。如果可行,就在某個(gè)操作中獲取它。當處理器結束與Mutex相關(guān)的共享資源使用時(shí),釋放該Mutex;此時(shí),另一個(gè)處理器可能獲取了Mutex,使用共享資源?;コ夂嗽谖锢砩喜⒉荒芊乐官Y源同時(shí)被多個(gè)處理器訪(fǎng)問(wèn)。運行在處理器上的軟件必須被設計為在訪(fǎng)問(wèn)相關(guān)共享資源之前總是獲取Mutex的。
在大部分情況下,多個(gè)處理器之間應該使用互斥核來(lái)保護共享資源。然而,也有一些不需要互斥核的,例如對于單方向或循環(huán)的消息緩沖隊列,此時(shí)只有一個(gè)處理器往存儲器的某個(gè)特殊位置寫(xiě)數據。
一般地,NiosII不支持多個(gè)處理器之間非存儲器外設的共享,NiosII硬件抽象層(HAL)庫也不支持。NiosIIHAL提供訪(fǎng)問(wèn)Mutex核的API函數如表l所列。
2.3 多處理器地址空間的重疊
在單處理器系統中,不允許多于一個(gè)的從外設具有相同的地址空間,原因是這將引起矛盾。然而,在多處理器系統中,只要外設被不同的處理器控制,那么不同的從外設就可以具有相同的基地址。
3 NiosII多處理器系統軟件設計
3.1 程序存儲器
在多處理器系統中,多個(gè)處理器可能使用同一個(gè)程序存儲器,每個(gè)處理器的程序必須存放在不同的位置。NiosII和SOPC Builder提供一個(gè)簡(jiǎn)單的存儲器分區模式,允許多個(gè)處理器在同一存儲器的不同區域運行各自的軟件。分區模式使用處理器的異常地址,可以在SOPC Builder中進(jìn)行設置。NiosII IDE負責根據異常地址計算出不同代碼段鏈接的位置。如果2個(gè)不同的處理器被鏈接到同一存儲器,那么每個(gè)處理器的異常地址用來(lái)決定處理器軟件存放的基地址,其末地址由下一個(gè)異常地址或者存儲器的末地址決定。對于每個(gè)處理器,軟件有5個(gè)主要的代碼段需要被鏈接到存儲器中的固定地址。分別是:
·text 實(shí)際的可執行代碼;
·rodata代碼段執行時(shí)所使用的常量數據;
·rwdata讀/寫(xiě)變量和指針;
·heap 動(dòng)態(tài)分配的存儲器;
·stack 函數調用參數和其他臨時(shí)數據。
在多處理器系統中,對于每個(gè)處理器,都希望使用連續的存儲區域存儲其所有的代碼段。在這種情況下,異常地址用來(lái)定義2個(gè)處理器之間代碼存放的分界。
值得注意的是,異常地址的低6位總是設置為Ox20,因為偏移量OxO是NiosII的復位地址,所以異常地址必須位于其他位置。偏移量選擇為Ox20,原因是它與一條指令的緩存行有關(guān)。Ox20字節的復位代碼初始化指令緩存行,然后跳轉到系統的起始代碼處。
3.2 啟動(dòng)地址
在多處理器系統中,每個(gè)處理器必須從自己的存儲區域啟動(dòng)。為了從同一個(gè)非易失性存儲器中的不同區域啟動(dòng)多處理器,簡(jiǎn)單地設置每個(gè)處理器的復位地址為所期望的啟動(dòng)地址。在啟動(dòng)地址之間要留出足夠的空間存放啟動(dòng)代碼。
NiosII Flash Programmet能夠將多個(gè)處理器的啟動(dòng)代碼編程到一個(gè)Flash器件中。Flash Programmer根據每個(gè)處理器的復位地址計算Flash內的編程地址。
3.3 Niosll IDE中多處理器系統的運行和調試
NiosII IDE中包含許多幫助開(kāi)發(fā)多處理器系統軟件的工具,最重要的是具有對多處理器同時(shí)進(jìn)行在片調試的能力。在多處理器系統上,多個(gè)debug(調試)可同時(shí)運行;每個(gè)處理器可以單獨暫停和恢復,也可以單獨設置每個(gè)處理器的斷點(diǎn)。某個(gè)處理器停在一個(gè)斷點(diǎn)處,并不影響其他處理器的操作。每個(gè)debug通道也可以單獨打開(kāi)和停止。在NiosII IDE中,利用一項稱(chēng)為“處理器集合(mul-tlprocessor collections)”的功能,一個(gè)操作就可以打開(kāi)多個(gè)處理器的debug通道。multiprocessor collections是被連接在一個(gè)配置名字下的每個(gè)處理器的debug配置組。使用multiprocessor collections的好處是無(wú)論何時(shí)打開(kāi)collections,NiosII IDE都可以打開(kāi)每個(gè)debug通道,而不用手動(dòng)打開(kāi)。也町以用一個(gè)操作停止multiprocessor col-lections,但是同時(shí)暫停和恢復multiprocessor collections目前不支持。
multiprocessor collections的打開(kāi)和停止不是同時(shí)的,這意味著(zhù)在collections中的處理器不能在同一個(gè)時(shí)鐘周期開(kāi)始執行代碼。事實(shí)上,不同處理器的啟動(dòng)可能有幾秒的延遲。multiprocessor collections的目的是方便打開(kāi)多處理器系統的debug通道,而不是為了同步處理器。如果需要在較短的時(shí)間內啟動(dòng)多個(gè)處理器,則需要構建單獨的硬件和軟件機制。
4 NiosII多處理器系統設計實(shí)例
下面將利用SOPC Builder建立一個(gè)基于標準模板的3處理器、共享片上存儲器的NiosII系統,之后在NiosIIIDE中為每個(gè)處理器建立一個(gè)軟件工程。系統功能是:3個(gè)CPU的軟件將產(chǎn)生要顯示的消息,使用硬件互斥核將所產(chǎn)生的不同消息放在共享的消息緩沖區中。cpul將連續檢查緩沖區中的新消息,如果發(fā)現新消息,就通過(guò)jtag_uart顯示出來(lái)。
實(shí)例的開(kāi)發(fā)環(huán)境是QuartusII 5.0或以上版本,開(kāi)發(fā)套件CycloneII Edition和niosII_cycloneII_2c35開(kāi)發(fā)板。
4.1 創(chuàng )建硬件系統
在標準硬件實(shí)例standard.qp的設計基礎上,增加2個(gè)處理器、2個(gè)定時(shí)器和1個(gè)硬件互斥核組件;另外增加1個(gè)消息緩存區message_buffer_ram(片上RAM),用作3個(gè)處理器的消息緩存區。按如下步驟連接共享資源:
?、偈褂眠B接矩陣,將SDRAM連接到每個(gè)處理器的指令和數據主端口。允許3個(gè)處理器訪(fǎng)問(wèn)SDRAM。
?、趯xt_ram_bus連接到每個(gè)處理器的指令和數據主端口。允許3個(gè)處理器訪(fǎng)問(wèn)外部RAM和Flash。
?、蹖essage_buffer_ram連接到每個(gè)處理器數據主端口。允許3個(gè)處理器訪(fǎng)問(wèn)該存儲器。
?、苋コ趍essage_buffer_ram和cpul指令主端口之間的缺省連接。
?、葸x擇System→Auto-Assign Base Addresses,為每個(gè)外設分配一個(gè)唯一的基地址。
完成以上操作后,系統配置如圖1所示。3個(gè)處理器的數據主端口與共享存儲器的同一從端口連接。因為cpul、cpu2和cpu3在物理上能夠同時(shí)將數據寫(xiě)到共享存儲器中,軟件必須仔細設計以保證存儲在共享存儲器上數據的完整性。注意:圖l所示的系統配置中,只有cpul的數據主端口與jtag_uart相連。
最后,為3個(gè)CPU設置復位和異常地址,創(chuàng )建和編譯系統,并下載FPGA的設計文件.sof文件到開(kāi)發(fā)板。
4.2 為多處理器系統創(chuàng )建軟件
在NiosII IDE環(huán)境下,為3個(gè)處理器系統分別創(chuàng )建6個(gè)軟件工程,為每個(gè)處理器創(chuàng )建一個(gè)應用工程和一個(gè)系統庫工程。之后對軟件工程進(jìn)行編譯、運行和調試。
軟件使用硬件Mutex共享一個(gè)消息緩存區。3個(gè)處理器分別寫(xiě)消息到消息緩存區(count)且循環(huán)加1。cpul讀消息且通過(guò)jtag_uart顯示消息。每個(gè)處理器運行同樣的C文件,但處理器的操作稍有不同。這是通過(guò)使用NiosII的cpuid實(shí)現的。在NiosII處理器系統中,某個(gè)處理器通過(guò)寫(xiě)其cpuid控制寄存器的值到Mutex寄存器的OwrqER域來(lái)對Mt-tex加鎖。cpuid寄存器保持一個(gè)靜態(tài)值,在多處理器系統中,該值唯一地識別一個(gè)處理器,且在系統創(chuàng )建時(shí)確定。軟件執行某個(gè)處理器的函數時(shí),首先檢查處理器的cpuid,如果cpuid正確,則執行相應函數。工程中的文件為hello_world_multi.c,其中將信息寫(xiě)入緩沖區的功能由以下程序段實(shí)現:
如果將信息從jtag_uart輸出,那么程序首先判斷id是否等于3。因為硬件設計時(shí),只有cpul與jtag_uart相連,而cpul的id的值為3(在系統創(chuàng )建時(shí)確定),cpu2、cpu3的id分別為1和2,且id的值等于cpuid控制寄存器的值加l,可在NiosII IDE環(huán)境下讀取cpuid控制寄存器的內容。其信息輸出的程序如下:
在System Library屬性中,第1個(gè)工程選擇jtag_uart為stdin、stderr和stdout,選擇cpul_timer為the Systemclock timer;第2個(gè)工程選擇cpu2_timer為System clocktimer,驗證stdin、stderr和stdout為null,因為這個(gè)處理器不與jtag_uart連接;第3個(gè)工程選擇cpu3_timer為Systemclock timer,其余同工程2。驗證這3個(gè)工程的SDRAM被選擇為Program memory、Read-only data memory、Read/write data memory、Heap memory和Stack memory。
分別經(jīng)編譯、下載、運行后,在終端上顯示這3個(gè)處理器產(chǎn)生的消息,如圖2所示。
結語(yǔ)
結果表明,3處理器系統通過(guò)硬件互斥核,實(shí)現了存儲器的共享。在此實(shí)例的基礎上,按同樣的方法添加處理器及相應的硬件組件,并開(kāi)發(fā)相關(guān)應用軟件,即可實(shí)現滿(mǎn)足不同需求的多處理器系統。
存儲器相關(guān)文章:存儲器原理
評論