FPGA Configuration 技術小結

Xilinx FPGA Configuration 技術小結

做了三年四個項目最近才第一次需要深入的搞一下FPGA 燒寫。在這裏簡單總結一下FPGA燒寫的具體過程和玩的花樣

大家常用的辦法

對於大部分人來說,至少入門時會用到的燒寫方式就兩種:

  1. 通過JTAG直接將bitsteam 燒錄到FPGA。 斷電後信息丟失。這種方式多用於發開調試階段,板子一直連着電腦。通過ISE 或者 Vivado (2020年開始估計還有Vitis)使用JTAG接口燒錄。
  2. 在設計release以後,到產品上一般都是把配置文件通過IDE工具保存存在Nor Flash裏。上電後自動編程FPGA。

較爲進階的一種方法

通常情況下這兩種方式也就可以滿足大部分需求了。開發調試直接JTAG。產品出貨前,配置文件通過JTAG接口,用VIVADO或者SDK等工具燒進Flash。之後把接口封起來。產品需要更新的時候,派技術支持去,重新打開接口,插上JTAG,把新的配置文件燒入Flash。

但是這次項目是個小型手持測量設備,JTAG接口只有在設備拆散狀態下通過擴展板才能使用。組裝好後FPGA只能通過Flash來編程。由於是個精密儀器,每次拆開再組裝,整個設備都需要重新校準,非常費事費力。組裝後更新Flash裏面的配置文件只能用別的辦法了。這種情況下常用的方法是通過一個和外界有通信能力的微控制器將image發送給FPGA, 再由FPGA寫入Flash。
圖一 圖1

這種remote update Xilinx提供了一種解決方案,相對應的Application Note 是 :
QuickBoot Method for FPGA DesignRemote Update (文檔號碼XAPP1081)
採用這種方案的前提是理解FPGA通過Flash配置的細節,所以以7系FPGA爲例先需要看一下這個文檔:
7 Series FPGAsConfiguration (UG470) 主要是看第五章:Chapter 5 Configuration Details

Xilinx 遠程燒錄FPGA方法

遠程燒錄一般是爲了設備出廠以後還需對FPGA進行更新或者升級。爲了避免在燒錄過程中新的配置文件損壞,導致FPGA不能正常啓動。通常採取的是雙保險策略,有個gold bitstream,是出廠是寫入Flash的,是測試過絕對可以啓動FPGA的,還有一個是update bistream,出廠時就是一個gold bitstream的copy,FPGA每次啓動都是默認寫讀取這個update bitstream。之後的更新也就是去重寫這個 update bitstream, 一旦在更新過程出了問題,比如突然斷電。update bistream損害或者殘缺,FPGA在嘗試從update bitstream啓動失敗後就會去讀取gold bitstream。這種方法保證了一個相對安全的update方法,所以也是一種非常經典的方法。

在這裏插入圖片描述圖2

去掉廢話來概括這種方法

每一個bitstream都長這樣:
在這裏插入圖片描述圖3

FPGA會先去找synchro word (7系列的spi接口的話就是0xAA995566)找到以後讀取首地址,然後跳到首地址,開始讀取所有的配置數據。
此文介紹的這種雙保險策略就是在Flash中存入兩個bitstream。但是精髓所在是這兩個Bitstream在內存中怎麼放。
如下圖所示,update的bitstream會被拆成兩段,synchron word和首地址會被存在goldbitstream前面,然後其他部分存在goldstream之後。而且update bitsteam尾部還會人爲加入一個CRC。
在這裏插入圖片描述圖4

這種鬼畜結構的目的
這種結構可以提供一種非常安全可靠的update模式。爲什麼會安全可靠。先來說一下這種結構下的update流程:
當我們想要update bistream的時候:

  1. 首先 update synchro word和首地址所在的sector(Flash裏可以擦除的最小單元)會被擦除。
  2. 然後開始在update所在的地方擦除所有內容,寫入新的bitstream。包括CRC。(這個CRC是生成bitstream的時候加入的。具體操作看下一章)。
  3. 當寫入結束後整個新寫入的內容會被讀出來計算CRC,然後和嵌入的CRC來做比較。當CRC一致時,說明在傳輸和寫入過程沒有出現問題。新寫入的配置內容完整,有效。這時update的synchro word和首地址纔會寫入最開始被擦除sector。

這樣一來,如果CRC不一致,說明這是個bad update,新寫入的配置內容不可用。那麼被擦除的synchro word 和首地址不會被寫入。第一個sector是空的。當FPGA上電後,它是在這個sector裏找不的update image的同步字和首地址的,繼續讀下去會讀到屬於goldbitstream的同步字和首地址。如下圖所示:
在這裏插入圖片描述圖5

實際操作步驟和文檔中的坑

首先好消息是,上述的這些Flash擦除,寫入,各種地址,sector,page等等Xilinx已經寫好了VHDL的模塊。可以直接拿來用。自己需要實現的是remote端往FPGA的數據傳輸。具體如下圖:
在這裏插入圖片描述圖6

具體實現步驟如下:

  1. 實現remote端的update程序,該程序需要讀取update image 然後通過某種接口和通信協議將image發送給FPGA。這一步該需求和情況自由發揮。例如物聯網的可以用藍牙或者WIFI。

  2. 實現FPGA端的數據接收。該模塊將數據寫入Xilinx提供的FlashProgrammer

  3. 下載XAPP1081文檔中的例子 KC705 Board Demonstrations, page 33。例子中兩個VHDL模塊按下圖實例化。注意 這兩個模塊必須共用一個時鐘,而且這個時鐘就是SPI的時鐘,所以注意不要太快。一般20Mhz一下。
    在這裏插入圖片描述圖7

  4. 集成前三條實現的模塊,調試。可以實現將數據從remote端發送給FPGA,經過SPiFlashProgrammer寫入Flash。

  5. 把bitstream格式轉換成mcs格式。將gold bistream。bit格式轉換成mcs格式。VIVADO下使用tcl 命令write_cgfmen -format mcs -interface spix1。一定要加 -interface spix1,不然所有的bits都會被swap!

  6. 通過Xilinx例子中提供的Perl Script生成 gold init image。script的輸入就是剛纔轉換的mcs格式的goldbitstream.mcs。輸出之一是gold init image這個image就是圖4中描述的那種鬼畜佈局的雙bitstream,只不過兩個bitstream是一樣的。update bitstream是gold的copy。

  7. 將gold inital.mcs通過VIVADO 或者PROMgen用JTAG直接燒入Flash

  8. 同樣的方式用Perl Script生成 update image。 輸入是xxx.mcs。輸出之一是xxx_update.mcs。這個就是上文所屬的加了CRC的update image。生成過程中perl script會給出Flash的首地址和結束地址。將SpiFlashProgrammer中的首尾地址改成這兩個地址。注意:因爲首尾地址是寫在VHDL裏的,也就是說Image的大小是固定的。爲了防止在未來,update image變大。可以預留一部分出來。例如:目前的大小是3.3MB。我們預留0.7MB給未來可能出現的更新。那麼我們需要生成的image需要4MB大。這是要給perl script一個附加的agrument: -imagesize 32

  9. 將xxx_update.mcs轉換成.hex文件。網上有不少工具可以。實在不行谷歌一下mcs格式,自己寫個script轉換一下。

  10. FPGA上電,取消SpiFlashProgrammer的reset。 remote的軟件讀取xxx_update.hex,傳輸給FPGA,經由SpiFlashProgrammer寫入Flash。

  11. 寫入後,查看Programmer的Status. Done輸出1,所有Error Port輸出是0的話,說明update成功!

  12. FPGA重新上電,檢查FPGA內是否是由新的image配置的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章