3. 固件与配置文件
FPGA 的固件通常被称为 bitstream(比特流)或配置文件(configuration file),它本质上是描述 FPGA 内部可编程逻辑资源(LUT、FF、BRAM、DSP、IO 以及路由开关)如何连接与配置的二进制数据。与处理器固件(如 ARM 的 HEX 或 Intel 的 UEFI)不同,FPGA 的 bitstream 不包含指令集,而是直接映射到硅片上的配置存储单元(CRAM)。理解 bitstream 的格式、压缩与加密机制,以及掌握 Vivado 与 Quartus 的生成流程,是设计可靠远程升级方案的基础。本章将深入剖析 bitstream 的内部结构、安全属性以及从工程到产物的完整生成链路。
上图展示了从工程编译到远程升级的完整链路。左侧是开发工具(Vivado/Quartus)生成 bitstream 的流程,中间是 bitstream 的格式与安全属性,右侧则是远程升级时固件从服务器到 FPGA 的流转路径。在实际项目中,开发者需要同时关注左侧的生成效率与中间的安全属性,才能保证右侧的远程升级既快又稳。
3.1 bitstream 格式深度解析
核心原理:bitstream 的层次化结构
FPGA 的 bitstream 并非简单的二进制大对象(BLOB),而是具有严格层次化结构的配置数据流。以 Xilinx 7 系列为例,bitstream 由 32-bit 同步字(0xAA995566)、配置命令(如 WRITE、READ、LFRM 等)、配置数据帧(Frame)以及 CRC 校验值组成。每个 Frame 对应 FPGA 内部的一列逻辑资源(CLB、BRAM、DSP 或 IO),Frame 的数量与器件型号直接相关。Altera(Intel)的 .rbf(Raw Binary File)格式则采用更简化的连续数据流,但同样包含同步头、配置数据和 CRC。
理解 bitstream 格式的关键在于:配置数据帧(Frame)是 FPGA 配置存储单元(CRAM)的最小寻址单位。远程升级时,如果采用部分重配置(Partial Reconfiguration),可以只更新特定区域的 Frame,而无需重写整个 bitstream。这要求开发者对 bitstream 的帧地址映射有精确掌握。
判断方法:如何识别与验证 bitstream 格式
在工程实践中,经常需要验证生成的 bitstream 是否正确。以下是几种常用的判断方法:
- 文件头检查:使用十六进制编辑器查看 .bit 文件的前 32 字节,应包含同步字 0xAA995566(Xilinx)或 0xFF 0xFF 0xFF 0xFF(Altera 的 .rbf 以连续 0xFF 开头)。
- CRC 校验:Vivado 生成的 bitstream 默认包含 CRC32 校验值。在远程升级时,MCU 应计算接收数据的 CRC32 并与 bitstream 末尾的 CRC 值比对,确保传输过程中数据未损坏。
- 回读验证:通过 JTAG 或 SelectMAP 接口回读 FPGA 内部的配置数据,与原始 bitstream 进行逐字节比对。Xilinx 的 iMPACT 或 Vivado 的 Hardware Manager 支持回读功能。
// 伪代码:MCU 端 CRC32 校验示例
uint32_t calc_crc32(uint8_t *data, uint32_t len) {
uint32_t crc = 0xFFFFFFFF;
for (uint32_t i = 0; i < len; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & (-(crc & 1)));
}
}
return ~crc;
}
// 注意:Xilinx bitstream 的 CRC 是倒序存储的,需进行字节序转换
案例拆解:从 .bit 到 .bin 的转换与验证
某工业网关项目采用 Xilinx Artix-7 FPGA,需要通过以太网远程升级固件。原始工程生成的 .bit 文件大小为 4.2MB,但直接通过以太网传输效率较低。工程师使用 Vivado 的 write_cfgmem 命令将 .bit 转换为 .bin 格式,去除了文件头,大小降至 3.8MB。随后,在 MCU 端编写了 CRC32 校验程序,对接收到的 .bin 文件进行校验。测试中发现,当网络丢包导致数据错误时,CRC 校验能够准确捕获错误,触发重传机制。经过 100 次连续升级测试,成功率达到 100%。
常见误区与总结
write_cfgmem 生成 .bin 文件,并确保其格式与 SPI Flash 的启动地址对齐(通常从 0x0 地址开始)。
总结:bitstream 格式是 FPGA 固件升级的基础。开发者必须理解 .bit、.bin、.rbf、.pof 等格式的区别与适用场景,并掌握 CRC 校验和回读验证等基本手段,才能确保远程升级的数据完整性。
3.2 bitstream 压缩与加密技术
核心原理:压缩与加密的必要性
FPGA 的 bitstream 通常较大(从几百 KB 到几十 MB),在远程升级场景中,传输时间与带宽成本是重要考量。bitstream 压缩技术通过去除配置数据中的冗余信息,可显著减小文件体积。Xilinx 的压缩算法基于 LZ77 变体,利用配置数据中大量重复的 0 和 1 模式进行编码。Altera 则采用更简单的稀疏编码(Sparse Encoding),对全零字节进行特殊标记。
加密则是保护 FPGA 知识产权(IP)和防止固件被逆向工程的关键手段。现代 FPGA(如 Xilinx UltraScale+、Intel Agilex)内置 AES-256 解密引擎,bitstream 在烧写前使用 AES 密钥加密,FPGA 在配置时自动解密加载。密钥可存储在 FPGA 内部的 eFuse 或 BBRAM(电池备份 RAM)中,确保密钥无法被外部读取。
| 特性 | Xilinx (Vivado) | Altera/Intel (Quartus) |
|---|---|---|
| 压缩算法 | LZ77 变体(默认开启) | 稀疏编码(需手动开启) |
| 加密算法 | AES-256 GCM(支持认证) | AES-256 CBC(部分器件支持) |
| 密钥存储 | eFuse / BBRAM | eFuse / 内部 SRAM |
| 压缩率 | 通常 50%-70% | 通常 30%-50% |
| 加密后压缩 | 不支持(先压缩后加密) | 不支持(先压缩后加密) |
操作流程:在 Vivado 中启用压缩与加密
在 Vivado 中,压缩默认开启,但加密需要额外配置。以下是标准操作流程:
- 生成加密密钥:使用
write_aes_key_file命令生成 256-bit 密钥文件(.nky 格式)。 - 配置加密属性:在约束文件(XDC)中添加
set_property BITSTREAM.ENCRYPTION.AESKEYFILE <key_file.nky>。 - 设置加密模式:添加
set_property BITSTREAM.ENCRYPTION.MODE AES256 [current_design]。 - 生成加密 bitstream:运行
write_bitstream,生成的 .bit 文件已加密。 - 烧写密钥:首次使用时,需通过 JTAG 将密钥烧写到 eFuse 或 BBRAM(使用
program_hw_devices命令)。
# Vivado Tcl 脚本示例
# 生成密钥文件
write_aes_key_file -file mykey.nky -key 0x00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF
# 设置加密属性
set_property BITSTREAM.ENCRYPTION.AESKEYFILE mykey.nky [current_design]
set_property BITSTREAM.ENCRYPTION.MODE AES256 [current_design]
# 生成加密 bitstream
write_bitstream -file encrypted.bit
案例拆解:加密 bitstream 的远程升级实战
某通信设备厂商需要防止其 FPGA 算法被竞争对手逆向。他们采用 Xilinx Kintex-7 FPGA,并启用了 AES-256 加密。在开发阶段,工程师将密钥存储在 BBRAM 中,方便调试。量产阶段,改为烧写 eFuse(一次性可编程),确保密钥不可更改。远程升级时,服务器下发加密的 .bin 文件,MCU 通过 SPI 接口将密文写入 SPI Flash。FPGA 上电后,自动从 Flash 读取密文,使用内部 AES 引擎解密并加载。测试表明,加密后的 bitstream 大小增加了约 2%(加密开销),但安全性大幅提升。即使攻击者从 Flash 中读出密文,也无法在没有密钥的情况下还原明文 bitstream。
常见误区与总结
- 误区一:压缩与加密可以同时开启。实际上,加密后的数据具有高熵,压缩算法无法有效工作。因此,Vivado 和 Quartus 均要求先压缩后加密,且加密后不再压缩。
- 误区二:加密 bitstream 可以防止所有攻击。加密只能防止静态逆向,但无法防止侧信道攻击(如功耗分析)。对于高安全场景,建议结合 FPGA 的物理不可克隆函数(PUF)或外部安全芯片。
- 误区三:所有 FPGA 器件都支持加密。低端器件(如 Spartan-6 的部分型号)不支持 AES 加密,设计时需确认器件选型。
总结:压缩与加密是远程升级方案中平衡效率与安全的关键技术。开发者应根据实际威胁模型选择是否加密,并合理配置压缩参数,以最小化传输时间与带宽消耗。
3.3 配置文件生成流程(Vivado / Quartus)
核心原理:从 RTL 到 bitstream 的完整链路
无论是 Vivado 还是 Quartus,生成配置文件的过程都遵循相似的步骤:综合(Synthesis)→ 布局布线(Place & Route)→ 时序收敛(Timing Closure)→ 生成 bitstream。综合将 RTL 代码转换为门级网表,布局布线将网表映射到 FPGA 的物理资源上,时序收敛确保设计满足时钟约束,最后生成 bitstream 文件。
在远程升级场景中,开发者需要额外关注两个环节:配置模式(如 SPI x4、SelectMAP)和启动地址(如 SPI Flash 的起始地址)。这些参数在生成 bitstream 时必须正确设置,否则 FPGA 无法从外部 Flash 正确加载固件。
操作流程:Vivado 与 Quartus 的配置生成步骤
| 步骤 | Vivado (Xilinx) | Quartus (Altera/Intel) |
|---|---|---|
| 1. 综合 | Run Synthesis → 生成 .dcp | Analysis & Synthesis → 生成 .vo |
| 2. 布局布线 | Run Implementation → 生成 .dcp | Fitter → 生成 .fit |
| 3. 时序分析 | Report Timing Summary → 检查 WNS/TNS | TimeQuest → 检查 setup/hold 裕量 |
| 4. 生成 bitstream | Write Bitstream → 生成 .bit/.bin | Assembler → 生成 .pof/.rbf |
| 5. 配置模式设置 | Edit Device Properties → 设置 SPI/SelectMAP | Device and Pin Options → 设置 Configuration Scheme |
案例拆解:多镜像远程升级的配置生成
某数据中心加速卡项目采用 Xilinx UltraScale+ FPGA,需要支持远程升级且具备回滚功能。工程师在 Vivado 中创建了两个配置镜像:Golden Image(出厂固件,存储在 SPI Flash 的 0x0 地址)和 Update Image(新固件,存储在 0x400000 地址)。生成 bitstream 时,通过 write_cfgmem 命令分别生成两个 .bin 文件,并设置不同的起始地址。FPGA 上电时,先加载 Golden Image,然后由 Golden Image 中的逻辑检查 Update Image 的版本号和 CRC。如果 Update Image 有效,则触发重配置加载 Update Image;如果无效,则继续运行 Golden Image。这种方案确保了升级失败时设备仍可正常工作。
# 生成 Golden Image (地址 0x0)
write_cfgmem -format bin -interface SPIx4 -loadbit "up 0x0 golden.bit" -file golden.bin
# 生成 Update Image (地址 0x400000)
write_cfgmem -format bin -interface SPIx4 -loadbit "up 0x400000 update.bit" -file update.bin
write_cfgmem 支持 -loadbit 参数指定多个镜像及其地址。
常见误区与总结
总结:配置文件生成流程是 FPGA 固件升级的源头。开发者需要熟练掌握 Vivado 和 Quartus 的配置生成步骤,特别是配置模式、启动地址和多镜像设置,才能为远程升级方案提供正确的固件输入。同时,应结合压缩与加密技术,在保证安全的前提下优化传输效率。