王鋒,呂天志,楊明洋
(中電科思儀科技股份有限公司,山東青島,266555)
采用SPIFlash 配置的FPGA 程序通常都是通過(guò)FPGA廠家提供的程序下載器進(jìn)行更新,一般儀器FPGA 程序的更新方式有兩種:
(1)打開產(chǎn)品機(jī)箱用專用程序下載器通過(guò)JETAG 接口更新FPGA 程序,這種方式操作復(fù)雜且需要專業(yè)人員完成;
(2)把FPGA 程序下載器的功能集成到電路板中,利用廠商提供的程序下載軟件更新程序,這種方案需要加入額外電路器件,增加了電路板器件的布局空間、功耗及設(shè)計(jì)成本。
鑒于一般儀器的CPU 模塊與FPGA 之間都有PCIe 總線連接,并且FPGA 和SPIFlash 直接連接,因此在FPGA正常工作時(shí)可以讓CPU 軟件通過(guò)PCIe 總線將要更新的FPGA 程序以文件形式先傳遞給FPGA,然后在FPGA 內(nèi)設(shè)計(jì)SPIFlash 芯片的燒寫控制邏輯,進(jìn)而實(shí)現(xiàn)SPIFlash 內(nèi)FPGA 程序的在線更新。
本文以7 系列FPGA 為例,7 系列FPGA的配置過(guò)程具備MultiBoot 和FallBack 機(jī)制—FPGA 在上電配置時(shí),MultiBoot 機(jī)制允許FPGA 選擇SPIFlash 中指定區(qū)域的比特流來(lái)配置,此版本比特流稱為update 鏡像,如果配置失敗,則觸發(fā)FallBack 機(jī)制將另一個(gè)性能良好的固定版本配置到FPGA 中,從而保證FPGA 可以正常工作,此版本比特流稱為golden 鏡 像。golden 和update 這 兩 個(gè) 鏡像會(huì)一起作為初始化鏡像用專用程序下載器下載到SPIFlash 中,在線更新僅對(duì)SPIFlash的update 鏡像區(qū)域進(jìn)行更新。本文在7 系列FPGA 的MultiBoot 和FallBack 機(jī)制的基礎(chǔ)上,闡述了一種在線更新Flash 內(nèi)FPGA 程序的方法,此方法不需要拆機(jī)連接程序下載器,更不需要增加額外硬件,在軟件界面上即可控制SPIFlash 內(nèi)FPGA 程序更新過(guò)程。
首先將golden 和update 鏡像一起作為SPIFlash 初始化鏡像下載到SPIFlash 中,然后需要更新FPGA 程序時(shí),使用在線程序更新功能升級(jí)SPIFlash 的update 鏡像即可。總體數(shù)據(jù)處理流程如圖1 所示。
圖1 SPIFlash 內(nèi)FPGA 程序在線更新的數(shù)據(jù)處理流程
如圖1 所示,在VIVADO 工程版本1.0 時(shí)生成golden和update 鏡像兩個(gè)FPGA 程序bit 文件;然后使用特定的tcl 命令將golden 和update 鏡像合并成一個(gè)MCS 文件作為Flash 初始化鏡像,并使用專用程序下載器將此MCS 文件下載到SPIFlash 中。當(dāng)VIVADO 工程版本升級(jí)為2.0 時(shí)需要更新SPIFlash 中FPGA 程序,此時(shí)使用在線程序更新功能升級(jí)SPIFlash 的update 鏡像即可。由于SPIFlash 內(nèi)存儲(chǔ)的FPGA 程序的數(shù)據(jù)格式為bin 文件,這里的bin 文件不同于VIVADO 生成的FPGA 程序bit 文件,因此CPU模塊可直接將2.0 版update 鏡像bin 文件送到FPGA 片內(nèi)RAM,然后在FPGA 內(nèi)設(shè)計(jì)SPIFlash 燒寫模塊從FPGA 片內(nèi)RAM 逐個(gè)字節(jié)讀取2.0 版update 鏡像bin 數(shù)據(jù)并將其寫入update 區(qū)域。
綜上所述,在7 系列FPGA 配置過(guò)程的MultiBoot 和FallBack 機(jī)制需要生成兩個(gè)版本的FPGA 程序,在此基礎(chǔ)上,主要通過(guò)CPU 軟件控制程序和FPGA 燒寫控制程序?qū)崿F(xiàn)SPIFlash 內(nèi)FPGA 程序的在線更新功能。
在VIVADO 工程約束文件中添加不同約束可編譯生成golden 和update 版FPGA 程序文件。如圖2所示,在基本的SPI 約束基礎(chǔ)上,選擇golden 約束,假設(shè)編譯生成名為vision_golden.bit 的golden 鏡像bit 文件;選擇update 約束,假設(shè)編譯生成名為vision_update.bit 的update 鏡像的bit 文件。
圖2 VIVADO 工程中生成多版本FPGA 程序的約束命令
在VIVADO 使用下列tcl 命令可生成SPIFlash 初始化鏡像MCS 文件,假設(shè)兩個(gè)版本的bit 文件存在于計(jì)算機(jī)D盤根目錄下,此tcl 命令如下:
其中,此tcl 命令指定了golden 鏡像在SPIFlash 內(nèi)存儲(chǔ)地址為0x00000000~0x01FFFFFF,update 鏡像存儲(chǔ)起始地址為0x02000000。鏡像區(qū)域的地址分配根據(jù)鏡像規(guī)模而定,各型號(hào)FPGA 的鏡像大小可查看UG470[10]文檔中的相關(guān)說(shuō)明。
CPU 模塊將update 鏡像bin 文件送給FPGA。FPGA程序一般為十幾到幾十MB,F(xiàn)PGA 片內(nèi)RAM 難以一次性緩存,此時(shí)CPU 模塊可以將update 鏡像bin 文件分包通過(guò)PCIe 總線以DMA 方式送給FPGA。設(shè)FPGA 燒寫模塊的RAM 為m 字節(jié)大小,update 鏡像bin 文件為n 字節(jié),則CPU 模塊需要將bin 文件拆分成N 包數(shù)據(jù),N=[n/m],第N 包數(shù)據(jù)不足m 字節(jié)的話,需將第N 包數(shù)據(jù)補(bǔ)充默認(rèn)字節(jié)“0xFF”到m 字節(jié)。執(zhí)行在線程序更新時(shí),CPU 模塊將第1 包bin 數(shù)據(jù)通過(guò)PCIe 總線寫到FPGA 的RAM 后啟動(dòng)在線燒寫流程,同時(shí)監(jiān)測(cè)FLASH 燒寫過(guò)程的各階段狀態(tài),正常燒狀態(tài)下FPGA 程序每寫完1 包數(shù)據(jù)就會(huì)通知CPU 模塊發(fā)送下一包數(shù)據(jù),若發(fā)生異常,F(xiàn)PGA 會(huì)將異常信息上傳至CPU 模塊。控制流程如圖3 所示。
圖3 SPIFlash 內(nèi)FPGA 程序在線更新CPU 軟件控制流程圖
CPU 模塊和FPGA 通過(guò)PCIe 進(jìn)行讀寫通信,如下所示:
首先,CPU 模塊在啟動(dòng)程序更新之前首先標(biāo)記設(shè)置RAM 為寫狀態(tài)、bin 為未傳完?duì)顟B(tài);
然后,確認(rèn)啟動(dòng)程序更新之后,執(zhí)行一次寫RAM 操作,并標(biāo)記RAM 是否寫滿和bin 數(shù)據(jù)是否傳完;
最后,CPU 模塊等待RAM 是否被讀空,若RAM 為空時(shí)檢測(cè)到bin 文件已送完則等待FLASH 燒寫完畢后結(jié)束程序更新過(guò)程,否則再次執(zhí)行一次寫RAM 操作。
首先需要根據(jù)update 鏡像的bin 文件大小和FPGA 內(nèi)RAM 資源情況開辟一塊緩沖區(qū)來(lái)接收update 鏡像bin 數(shù)據(jù),緩沖區(qū)越大,CPU 模塊向FPGA 傳遞的bin 數(shù)據(jù)包數(shù)就越少,F(xiàn)PGA 資源占用越大。由于燒寫過(guò)程和FPGA 正常功能不沖突,以及SPIFlash 燒寫是臨時(shí)占用RAM 資源,因此在線燒寫可以復(fù)用其他模塊的RAM,這塊RAM 在FPGA正常工作時(shí)用于其他功能,這樣可實(shí)現(xiàn)RAM 資源共享,節(jié)省RAM 資源。
用戶通過(guò)界面啟動(dòng)在線燒寫功能后,首先執(zhí)行SPIFlash 的update 鏡像區(qū)域擦除,擦除完畢后,CPU 模塊將update 鏡像bin 數(shù)據(jù)通過(guò)PCIe DMA 分包送到FPGA的RAM,F(xiàn)PGA 的燒寫模塊將bin 數(shù)據(jù)逐個(gè)字節(jié)地傳遞給SPIFlash,并同時(shí)接收燒寫模塊輸出的過(guò)程標(biāo)記或異常信息。因此FPGA 燒寫程序分為數(shù)據(jù)傳遞模塊和燒寫模塊。
1.4.1 數(shù)據(jù)傳遞模塊
FPGA 負(fù)責(zé)接收每包update 鏡像bin 文件,并將燒寫過(guò)程中各階段完成或錯(cuò)誤標(biāo)記上傳給CPU 模塊。每傳遞完1 包bin 數(shù)據(jù),F(xiàn)PGA 通知CPU 模塊繼續(xù)傳遞下一包bin 數(shù)據(jù),直到所有bin 數(shù)據(jù)包傳遞結(jié)束并且全部寫入SPIFlash。由于SPIFlash 的update 鏡像區(qū)域是事先分配的一塊區(qū)域,當(dāng)所有bin 數(shù)據(jù)全部寫入FLASH 時(shí),update 鏡像區(qū)域一般沒有被寫滿,此時(shí)燒寫模塊并不會(huì)返回FLASH 燒錄完成的標(biāo)志;因此FPGA 需要再向update鏡像區(qū)域剩下的空間中寫填充字0xFF,直到update 鏡像區(qū)域末尾燒寫模塊才會(huì)返回FLASH 更新完成標(biāo)記。
每當(dāng)一包bin 數(shù)據(jù)寫入RAM,F(xiàn)PGA 捕獲RAM 寫完標(biāo)記后使能讀狀態(tài)標(biāo)記,在RAM 讀空之后清零RAM 讀狀態(tài)標(biāo)記。在SPIFlash 的update 鏡像區(qū)擦除成功后,若讀狀態(tài)標(biāo)記有效并且bin 文件的數(shù)據(jù)未傳遞結(jié)束,則逐個(gè)讀取RAM 數(shù)據(jù)送給SPIFlash,當(dāng)RAM 讀空時(shí)清零讀標(biāo)志。當(dāng)讀狀態(tài)標(biāo)記有效并且bin 文件數(shù)據(jù)傳遞結(jié)束時(shí),說(shuō)明RAM中存儲(chǔ)的是bin 文件的最后一包數(shù)據(jù),然后進(jìn)入寫填充字階段,直到SPIFlash 燒寫完成。編制數(shù)據(jù)傳遞狀態(tài)機(jī),如圖4 所示。
圖4 SPIFlash 內(nèi)FPGA 程序在線更新FPGA 數(shù)據(jù)傳遞控制狀態(tài)機(jī)
其中,在flash_programm_wait 狀態(tài)等待SPIFlash的ID 校驗(yàn)和存儲(chǔ)區(qū)擦除;針對(duì)CPU 模塊傳遞來(lái)的N 幀數(shù)據(jù)包,第1 到N-1 幀的字節(jié)是在flash_programm_write狀態(tài)傳遞;第N 幀的字節(jié)是在flash_programm_write_ex狀態(tài)傳遞;update 區(qū)域剩余空間的默認(rèn)字節(jié)“0xFF”在flash_programm_write_ex1 狀態(tài)傳遞;在這四種狀態(tài)中,如果發(fā)生ID 校驗(yàn)、或燒寫錯(cuò)誤,就停止?fàn)顟B(tài)機(jī),并將相應(yīng)錯(cuò)誤標(biāo)記傳遞給CPU 模塊。
1.4.2 燒寫模塊
燒寫模塊實(shí)現(xiàn)FPGA 和SPIFlash 的通信,此模塊將SPIFlash 控制指令或數(shù)據(jù)通過(guò)并串轉(zhuǎn)換后經(jīng)SPI 訪問(wèn)FLASH,實(shí)現(xiàn)SPI FLASH 的ID 檢測(cè),F(xiàn)LASH 存儲(chǔ)區(qū)擦除、數(shù)據(jù)傳遞以及異常檢測(cè)等功能。燒寫模塊內(nèi)部接口如圖5所示,燒寫模塊完全由FPGA 實(shí)現(xiàn)。
圖5 SPIFlash 內(nèi)FPGA 程序在線更新FPGA 程序燒寫模塊接口圖
其中燒寫控制模塊SpiFlashProgrammer 的操作邏輯為:
(1) 初始化;
(2) 檢測(cè)ID,讀取并檢驗(yàn)FLASH 存儲(chǔ)設(shè)備標(biāo)志;
(3) 刪除包含update 鏡像的FLASH 扇區(qū);
(4) 編碼update 區(qū)域。對(duì)于update 鏡像區(qū)域每一頁(yè):
a.發(fā)送頁(yè)編碼命令,
b.發(fā)送當(dāng)前頁(yè)的每個(gè)字,如果處于當(dāng)前頁(yè)的末尾,則進(jìn)入c 步驟,
c.使能內(nèi)部FLASH 頁(yè)編碼操作,
d.等待直到FLASH 狀態(tài)準(zhǔn)備好,即內(nèi)部頁(yè)編碼已完成。
(5)設(shè)置鏡像升級(jí)完成標(biāo)志。
燒寫成功時(shí)會(huì)設(shè)置升級(jí)完成標(biāo)志,在任何步驟發(fā)生錯(cuò)誤時(shí),也會(huì)設(shè)置升級(jí)完成標(biāo)志,此時(shí)CPU 模塊應(yīng)根據(jù)燒寫過(guò)程返回的狀態(tài)檢測(cè)是否有錯(cuò)誤發(fā)生,若有則顯示錯(cuò)誤信息,否則顯示各階段的完成標(biāo)志。
SPIFlash 內(nèi)FPGA 程序更新過(guò)程需要考慮并串轉(zhuǎn)換模塊SpiSerDes,此模塊和燒寫控制模塊連接。SPI 總線有兩個(gè)雙向串行數(shù)據(jù)線,SpiSerDes 模塊在向SPI 總線串行化1字節(jié)的同時(shí),將SPI 總線發(fā)來(lái)的1 字節(jié)輸入數(shù)據(jù)并行化。SpiSerDes 模塊的4 個(gè)引腳必須連接到已連接SPIFlash 的FPGA 引腳上。其中CCLK 引腳作為在線燒寫時(shí)鐘,默認(rèn)為FPGA 配置時(shí)鐘專用管腳,在上電配置完成后默認(rèn)不能作為普通管腳使用,如果想在配置之后將CCLK 用作在線燒寫時(shí)鐘,即用作普通管腳,則需要將連向SPI 時(shí)鐘的時(shí)鐘信號(hào)輸入到STARTUPE原語(yǔ)中,并且不需要對(duì)CCLK做額外的約束。
圖6 展示了FPGA 程序燒寫模塊仿真時(shí)序圖,update的bin 數(shù)據(jù)分三幀傳遞給FPGA 的RAM,F(xiàn)PGA 將每幀數(shù)據(jù)燒寫到SPIFlash 的update 鏡像區(qū)域,并且在第三幀數(shù)據(jù)送進(jìn)SPIFlash 之后繼續(xù)傳遞默認(rèn)字節(jié)“0xFF”,當(dāng)寫滿SPIFlash 的update 鏡像區(qū)域時(shí),在線更新結(jié)束。
圖6 FPGA 程序燒寫模塊仿真時(shí)序圖
在整機(jī)軟件界面上開辟一個(gè)程序更新界面,如圖7 所示。界面顯示有當(dāng)前版本號(hào)、更新版本號(hào)、提示信息和可能錯(cuò)誤信息以及更新檢測(cè)和開始更新兩個(gè)按鈕。當(dāng)保存著待更新update 鏡像bin 文件的U 盤或SD 卡連接儀器設(shè)備后,點(diǎn)擊更新檢測(cè)按鈕,軟件會(huì)檢測(cè)并顯示待更新update 鏡像bin 文件的版本,點(diǎn)擊開始更新按鈕即可執(zhí)行在線更新。在更新過(guò)程中若發(fā)生錯(cuò)誤,則更新過(guò)程立即停止,并在界面上顯示錯(cuò)誤信息,否則更新結(jié)束時(shí),界面會(huì)提示更新成功。
圖7 SPIFlash 內(nèi)FPGA 程序在線更新用戶界面
在某已投產(chǎn)的項(xiàng)目中,在線更新功能取得良好的應(yīng)用效果,得到技術(shù)人員的肯定。項(xiàng)目FPGA 程序編譯文件大小約為10MB,一次完整的在線更新時(shí)間不到2 分鐘,如表1 所示。
表1 SPIFlash內(nèi)FPGA程序在線更新運(yùn)行時(shí)間
本文在7 系列FPGA 配置過(guò)程具備MultiBoot 和FallBack 機(jī)制的基礎(chǔ)上,設(shè)計(jì)一種通過(guò)主機(jī)界面即可操作的SPIFlash 內(nèi)FPGA 程序在線程序更新方案。本方案充分利用一般儀器上CPU 模塊與FPGA 之間有PCIe 總線連接,并且FPGA 和SPIFlash 直接連接的特點(diǎn),讓CPU 模塊通過(guò)PCIe 總線將FPGA 程序數(shù)據(jù)分包傳遞給FPGA,然后由FPGA 燒寫進(jìn)SPIFlash,這樣使用較小的RAM 空間即可實(shí)現(xiàn)SPIFlash 內(nèi)較大update 程序鏡像更新。并且本方法不影響設(shè)備正常工作,不增加額外硬件電路,不需要連接程序燒寫器,僅僅需要裝載FPGA 程序的U 盤等存儲(chǔ)設(shè)備即可在通過(guò)操作燒寫界面執(zhí)行SPIFlash 內(nèi)FPGA 程序更新,非常便于用戶遠(yuǎn)程更新設(shè)備程序,并大大降低了儀器設(shè)備FPGA 程序升級(jí)的工作量。