Zynq動態更新FPGA比特流


ZYNQ-7000的結構是ARM+FPGA,在脫離JTAG的情況下,PL的配置只能通過PS來完成。正常上電的加載順序是,FLASH/SD - > FSBL -> PL BITSTREAM -> PS ELF,那么在整個系統全部加載完成以后是否有辦法重新給PL配置程序呢?答案是肯定的。

XILINX官方的BSP裸機例程里有xdevcfg的驅動代碼,里面有個例程叫做POLL_EXAMPLE,就是實現PS配置PL比特流的,可以將指定的DDR空間里的數據給FPGA加載,如果這段數據是正確的比特流,那么FPGA就可以成功加載。但是這個代碼經過實測,在PL已經CONFIG DONE的情況下是不工作的,我們要對其進行修改。

首先要注意的是,加載所需要的文件是不能用.bit文件的,要用bin文件。而且在Bitstream Settings里面勾選_binfile option也是不行的,必須用命令生成。坑爹的xilinx網上一大抄文檔都是說progmem命令的,但是這個命令在vivado里已經被刪掉了,替代命令叫write_cfgmem。參數很惡心,如下:

write_cfgmem -format bin -loadbit "up 0x0 ZynqSys_wrapper.bit" -file ZynqSys_wrapper.bin -size 128 -force -interface SMAPx32 -disablebitswap

我用的芯片型號為7z015,生成的bin文件大小為0x3591C。

再回到剛才的例程,主函數簽名有兩個關鍵的宏定義,一個是BITSTREAM_LOCATION,默認的是0x40000001,這個地址實際上是GP-AXI MASTER地址空間的,並不是DDR里面的,比如我要把比特流放在0X30000000開始的位置,那么這里要改成0x30000001,如注釋所寫,最后兩個比特為2‘b01代表這是最后一次DMA傳輸(實際上也就這一次)。地址最好四字節對齊。第二個宏定義是BITSTREAM_SIZE_WORDS,這里是以32bit表示的大小,即0x3591C / 4。所以前面生成的bin文件大小必須是4的倍數,如果不是,肯定有問題。

改完宏定義以后,用jtag模式啟動zynq,加載這段程序,利用xilinx tools里面的dump/restore memory功能把bin文件拷貝到0x30000000的空間里去,執行程序,應該可以看到config_done有效了;然而如果上電的時候已經加載了PL比特流,這段程序仍然無用,因為需要對PL進行一次復位操作。文檔UG585里面在一個極其猥瑣的位置描述了如何通過PS對PL執行清除比特流並復位的操作流程:

Example : Configure PL via PCAP Bridge

3 Initialize the PL

a.Set devcfg.CTRL[PCFG_PROG_B] bit = 1;

b. Set [PCFG_PROG_B] bit = 0.
c. Wait for devcfg.STATUS [PCFG_INIT] bit = 0.
d. Set [PCFG_PROG_B] bit = 1.
e. Wait for [PCAP_INIT] bit = 1.

其中e這個步驟,我找了很久也沒找到所謂的PCAP_INIT在哪里,不知道是否是筆誤,我的理解是這里應該是PCFG_INIT,PCFG_INIT為1代表PL READY FOR BITSTREAM PROGRAMMING。
把這個流程加在xdevcfg_transfer函數的最前面,在加載操作以前先對PL執行復位。
這個加載操作是很快的,CONFIG_DONE指示燈閃一下就立刻亮了,配置成功。



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com