这一篇在干嘛?

假如你手上有一块 EG4S20 开发板,想让同一个芯片既能跑流水灯、又能跑按键消抖,切换时还不用重新接下载器烧录——这就是 MULTI BOOT(多启动)要解决的事。这篇笔记带你从原理到实操,完整走一遍多镜像启动的全流程。

先搞懂几个词

术语全称意思
EG4Eagle4安路的一个 FPGA 系列,EG4S20 属于这一族
FPGAField Programmable Gate Array现场可编程门阵列,可以反复改写电路的芯片
TDTang Dynasty安路官方的 FPGA 开发软件,综合、布局布线、下载都靠它
SPISerial Peripheral Interface串行外设接口,FPGA 和配置 Flash 之间就用它通信

MULTI BOOT 是什么?和 DUAL BOOT 有啥区别?

MULTI BOOT(multi boot)的意思是:你可以在 SPI Flash 里存放两套或者更多套 FPGA 位流(bitstream,就是编译出来的”程序”)。上电后 FPGA 先加载 Primary 位流(第一套),而这第一套代码里可以发出跳转信号,让 FPGA 跳到 Flash 的指定地址,重新加载另一套位流

它和常见的 DUAL BOOT(双启动)长得很像,但思路完全不同:

对比点DUAL BOOT(双启动)MULTI BOOT(多启动)
什么时候跳第一套位流加载失败后,自动跳到第二套用户给的跳转信号触发,跳到指定地址
两套位流的关系功能相同,第二套只是备份,用于容错功能不同,用来在多种功能之间切换
典型场景程序损坏后的”保命”兜底运行中切换功能,比如今天跑流水灯、明天跑通信实验

一句话总结:DUAL BOOT 是”坏了自动换备份”,MULTI BOOT 是”我想切就切”,而且可以不止两套。

最佳实践

如果只是担心固件写坏、芯片变砖,用 DUAL BOOT 放一份相同功能的备份就够了;需要在多个功能之间动态切换,才上 MULTI BOOT。

Flash 里长什么样:多配置镜像布局

先了解硬件约束:

  • EAGLE 系列的配置位流长度大约 4.8M~6M bits(具体大小还和 BRAM 初始化数据的长度有关),所以配置芯片容量必须 ≥ 6M bit
  • 配置芯片用工业标准串行 SPI 接口 Flash,比如 M25Pxx、SST25LFxxx、S25FLxxx 等型号都可以,但要求读命令为 0x03
  • 在 MSPI 模式下,当 SPI Flash 容量 大于 12M bit 时,EAGLE FPGA 才支持 MSPI MULTI BOOT,也就是能放两套以上的位流。

把两套以上的位流放进 Flash 后,空间大致是这样分的(图 1 的示例布局):

Flash 地址内容
0x000000 ……Primary bitstream(第一套位流)
0x0A0000 ……Second bitstream(第二套位流)
0x140000 ……Third bitstream(第三套位流)

注意

Primary 位流的起始地址必须固定放在 0x000000,这是上电默认加载的位置;而第二套、第三套位流的起始地址,可以根据 bit 文件大小和 Flash 容量自定义,上面的地址只是示例,不是硬性规定。

核心模块:EG_LOGIC_MBOOT

想让 FPGA 会”跳转”,必须在 FPGA 代码里添加多启动控制模块 EG_LOGIC_MBOOT。它的工作逻辑很直白:

  • 地址模式为 STATIC(静态)时,使用参数里设好的静态启动地址 static_addr
  • 地址模式为 DYNAMIC(动态)时,使用 dynamic_addr 端口实时传入的地址;
  • 这个地址是跳转地址的高 8 位
  • rebootn 收到低电平信号时,FPGA 就跳到对应地址,重新加载从那里开始存放的另一套位流。

端口和参数

端口方向位宽功能
rebootn输入1重启控制信号,低电平有效
dynamic_addr输入8动态重启地址,即 SPI Flash 的高 8 位地址
参数可选值默认值说明
ADDR_SOURCE_SEL”STATIC” / “DYNAMIC""STATIC”启动模式,动态或者静态
STATIC_ADDR8 位地址8’b00000000静态启动地址,为 Flash 地址的高 8 位

怎么用?

这个模块只支持原语例化(直接在 Verilog 里手写例化),不支持通过 IP Generator 图形界面生成。

Verilog 例化模板长这样:

EG_LOGIC_MBOOT #(
    .ADDR_SOURCE_SEL ("STATIC"),
    .STATIC_ADDR (8'b00000000))
MBOOT_inst (
    .rebootn (reboot_n),
    .dynamic_addr (addr)
);

最佳实践

如果你只想固定跳到一个地址,用默认的 “STATIC” 模式、把 STATIC_ADDR 设好就行;如果想让运行中的逻辑(比如按键、通信命令)决定跳哪儿,就用 “DYNAMIC” 模式,从端口喂地址。

用 TD 软件烧写:download 工具操作步骤

在每套代码里都添加好 EG_LOGIC_MBOOT 模块后,就可以生成两套或多套 bit 位流,然后按下面的步骤用 TD 的 download 工具烧写:

  1. 把目标板通过下载器连接电脑,打开 TD 的 Download 界面,找到器件后,在 mode 栏选择 multi boot 模式。
  2. 单击 add,把两套或多套位流添加进来。每套位流都要单独烧写,并为其填写 Start address(该位流在 Flash 中存放的起始地址),例如第一套位流填 0x000000,第二套位流填 0x0A0000。
  3. 设置好后,选中当前要烧写的 bit 位流,点 Run,即可把它下载到 FLASH 中。

下面两张图就是 download 工具里配置第一套和第二套位流的实际界面:

TD download 工具中选择 multi boot 模式并配置第一套位流的起始地址

download 工具中添加并烧写第二套位流到 0x0A0000 起始地址的界面

实战例程:三套位流按灯切换

手册给出了一个完整例程:在 EG4X20BGA256 开发板上,TD 软件工程生成三套 bit 位流,通过按键发出跳转信号 reboot_n,让 FPGA 重新加载新的位流,实现不同 LED 闪烁效果的切换。我们把三套位流分别叫 bitstream0、bitstream1、bitstream2,上电先跑 bitstream0,按一次键切到下一套,循环往复。

第一步:规划位流存储空间

外置 Flash 型号是 M25P16,容量 16Mb(2MB)。算一笔账:

2MB = 2^21 = 2^5 × 2^16 = 32 × 64KB

也就是 32 个 64KB 的 block(每次写入的最小长度)。而 EG4 示例工程生成的 bit 位流为 614KB,即占用 10 个扇区。算下来这块 Flash 最多可以存入 3 套位流,规划如下:

位流占用扇区起始地址跳转地址(下一套)
bitstream0sector00~sector090x0000000x0a0000
bitstream1sector10~sector190x0a00000x140000
bitstream2sector20~sector290x1400000x000000

注意看跳转地址一列:三套位流首尾相接、循环跳转,bitstream2 跳回 bitstream0,形成闭环。

第二步:代码里添加控制模块

每套代码中都添加 EG_LOGIC_MBOOT,这次把 ADDR_SOURCE_SEL 设为 “DYNAMIC”,由各套代码分别给 dynamic_addr 赋不同的值(别忘了,这是跳转地址的高 8 位):

  • 第一套 bit 的 dynamic_addr 赋 0x0a(对应跳到 0x0a0000)
  • 第二套 bit 的 dynamic_addr 赋 0x14(对应跳到 0x140000)
  • 第三套 bit 的 dynamic_addr 赋 0x00(对应跳回 0x000000)

例化代码:

EG_LOGIC_MBOOT #(
    .ADDR_SOURCE_SEL ("DYNAMIC"),
    .STATIC_ADDR (8'b00000000))
MBOOT_inst (
    .rebootn (reboot_n),
    .dynamic_addr (addr)
);

第三步:download 工具烧写三套位流

参考上一节的步骤,用 download 工具把 3 套 bit 位流分别添加、分别烧写:第一套 Start address 填 0x000000,第二套填 0x0A0000,第三套填 0x140000。三套都烧完后,按一下开发板上的按键就能切换位流重新加载,看到不同 LED 闪烁效果的切换。

踩坑提醒

这两个坑一定要避开

  1. 烧写方式:代码里加了 EG_LOGIC_MBOOT 后,只能用 download 工具的 MULTI BOOT 模式烧写 bit 文件。如果直接用 JTAG 模式烧写,因为没有填写 bit 文件的起始地址,可能会导致烧写后功能无效。
  2. 空间规划:一定要根据 bit 文件大小和 Flash 容量,提前规划好位流的存放位置,避免出现位流存放位置冲突或者存储空间不足的情况(比如例程里 614KB 的位流要留足 10 个扇区)。

自测一下