如何通过镜像加载技术在FPGA运行中无缝切换比特流文件?
摘要:title: FPGA切换启动镜像(可重构技术) date: 2024824 11:52:25 cover: true mathjax: false summary: 如何使用ICAPE原语来完成比特的运行中切换 categories:
补档声明
由于我的博客服务器和备案到期,所以选择转移到博客园平台来进行保存和记录。以后也有可能会在上面不定期更新一些技术类博客。
前言
这是一种无需重新烧录比特就能切换FPGA正在运行的比特的方法。
分为两种,一种是全局可重构,也可以叫做启动镜像切换,本质上是将两份或多份比特流同时固化到FLASH中,在运行过程实时中切换使用哪一份比特,这是基于NOR FLASH的片上执行特性(暂且这么称呼,本质上是因为NOR只需要给地址就能出数据,没有译码转址这一过程) 。所以对于配置了NOR FLASH的FPGA板卡,我们可以通过ICAP原语来给出比特流加载的同步字,然后送入加载基地址,并给出加载命令,来进行当前执行比特流的切换。
另一种是部分可重构,这种要更复杂一点,但是本质上只不过是把重加载全局比特变成了重加载部分模块的比特,所以会有个画pblock的过程,相比于全局可重构,流程会复杂许多,而且如果是中间模块的替换,由于输入输出端口的变化,会造成一些时序约束的问题,且无法直接使用OOC IP核,只能把IP核做成网表再调用,在我自己的工程上对于资源利用率的降低作用不显著。本文就只着眼全局可重构。
全局可重构我目前探索出来的路径有两条,一条已经实现,就是后文的合并bit到一个mcs文件中,然后使用icape原语启动。另外的一条路是上位机通过pcie的dma通道,流式传输要切换的比特到板卡上,完成比特的切换,这条路还在摸索,如果能够完成的话,那么对于机箱上的FPGA板卡来说,就可以让上位机保存多份比特,在运行之中随便切换,完成FPGA板卡功能的更新或者切换。
下面仅从怎么做的描述如何将两个工程的比特流合并到同一个mcs文件下,并使用这个mcs来对fpga进行烧录固化,并编写简单的代码来调用icape原语来对启动地址进行切换,以达到不重新烧写比特就能进行工程的切换的方法。
有关FLASH的几个工程xdc约束
需要添加到工程的xdc中
############## FLASH ##################
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
set_property CONFIG_MODE SPIx1 [current_design]
# 如果 FLASH 大小大于等于 256Mb,要增加如下约束,否则高于24位的地址会被忽略,导致无法启动对应的 update 镜像
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]压缩比特,这是一个蛮有用的选项,如果不使用压缩比特的话,那么任何一个工程,不论代码有多简单或者多复杂,都会生成一个同样大小的,未经过压缩的比特,对于7k325t会占用大概11MB的大小,更复杂的片子会更大。如果启用了,就会根据工程代码的复杂程度对比特进行压缩,一般来说都挺有效果的,能把最简单的LED流水灯工程压缩到几百KB的水平。能把我的工程压缩到5.5MB左右大小
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]设置烧录速度,50M是SPI时钟线上的时钟频率,一般的SPI存储芯片都能支持这个速率。
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1SPI宽度,这是用于控制烧录程序的接口的,因为我们要使用Fallback,所以这里必须是x1
set_property CONFIG_MODE SPIx1配置模式宽度,和上面一样
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] 启用32bit地址线模式,如果FLASH大小大于等于256Mb,也就是32MB,需要启用这个约束,并且写入镜像的地址线的方法需要变动,见后文。我的板子上的s25fl256大小正好是256Mb,所以得开。
