STARTUPE2 启动原语:FPGA 启动后把 CCLK 等专用配置脚借给用户逻辑
做过 QSPI 固化的人大多遇到过这个需求:设备已经焊死在现场,想升级 Flash 里的镜像,却不想(或不能)拆下来用烧录器写。一个自然的想法是——FPGA 既然能从这颗 SPI Flash 启动,启动之后能不能反过来当主设备,自己给 Flash 擦写?答案是可以,但中间隔着一道硬件级的开关:CCLK、FCS_B 这几只脚在硅片上是专用配置脚,普通用户逻辑连线够不到它们,必须例化 STARTUPE2 启动原语才能接管。前置时序背景建议先读 FPGA 上电配置时序:从电源爬升、POR 到 DONE 与 GTS/GWE 启动序列全解,配置脚在主串/主并模式下的分工见 FPGA 配置方式有哪几种,操作层面的 JTAG 下载与固化流程见 FPGA 入门 32:比特流下载与固化。
读这张对照卡要抓住「两个主人、一道开关」:左栏是配置期,专用脚只听配置状态机的;右栏是启动结束后,STARTUPE2 原语成为引脚的复用开关,用户逻辑通过它把自己的时钟和片选送出去。注意底部那行触发条件——EOS 并不是一个自动跳线开关,它只表示配置电路正式交权;引脚要不要接过来、什么时候接,仍由你写的三态控制位逐只决定。
本文要回答的问题
- FPGA 配置完成后,CCLK、FCS_B 这几只专用脚默认是什么状态,为什么普通 RTL 信号驱动不了它们?
- EOS(End Of Startup)和 USRCCLKO、USRCCLKTS 之间是什么关系,三态位为什么是「低电平输出使能」,写反了会怎样?
- STARTUPE2 原语有哪些端口,最小可用例化长什么样,哪些脚其实不经过原语(DIN/DOUT)?
- 启动后反过来给 SPI/BPI 配置 Flash 在线烧镜像,链路怎么接,擦写期间有哪些掉电与变砖风险?
- DONE、INIT_B、PROGRAM_B 三个脚分别是什么电气类型,怎样参与板级复位与重配控制?UltraScale 的 STARTUPE3 又有什么不同?
一、问题的起点:为什么需要 STARTUPE2 启动原语
FPGA 的引脚分两类。大多数封装脚是用户 I/O,比特流加载完成后归你的设计支配,在约束文件里指定电平标准即可。另一小批是专用配置脚——CCLK、DONE、PROGRAM_B、INIT_B、FCS_B 等,它们在硅片上直接连到配置状态机,不进入通用布线矩阵。主 SPI 模式启动时,配置状态机就是通过 CCLK 发时钟、FCS_B 拉片选、D00/D01 收发数据,从外部 Flash 把比特流读进来的(这套主从关系见配置方式篇)。
矛盾由此而来:启动结束后,配置状态机停车了,可这批脚还连在它身上。如果你想在运行期复用它们——最典型的就是在线烧录启动 Flash——通用布线资源里根本没有到达 CCLK 焊盘的路径。Xilinx 在 7 系(Spartan-7 / Artix-7 / Kintex-7 / Virtex-7)给出的唯一通道,就是 STARTUPE2 启动原语:一个嵌在配置电路旁边、带三态控制的复用开关。
这张图的读法:灰色是配置期的旧主人与引脚本身,绿色 EOS 是交权信号,橙色是启动后的新主人。注意 EOS 只指向用户逻辑——它是一道「时间许可」,告诉用户逻辑现在接管安全了;真正连到复用开关的,是用户逻辑侧的 USRCCLKO 与三态位。换句话说,EOS 管「什么时候可以」,TS 位管「接不接、接哪只」。图中每只脚独立三态,意味着你可以只借 CCLK、不借 DONE,互不影响。
二、端口逐个看:时钟、片选、DONE 与三个不常用口
STARTUPE2 的端口可以分成四组。下面这张表按用途归类,具体端口宽度与属性以 Vivado 自带原语模板(Libraries Guide)为准,移植时不要手抄旧版本。
| 端口 | 方向 | 含义与接法 |
|---|---|---|
EOS | 输出 | End Of Startup,启动序列完成后拉高,常作为接管逻辑的复位释放条件 |
CFGCLK / CFGMCLK | 输出 | 配置逻辑内部时钟与内部振荡器时钟,一般监控用,不拿来当主时钟 |
CLK | 输入 | 用户启动时钟;仅当比特流选项把启动时钟源选成 User Clock 时才需要接 |
USRCCLKO | 输入 | 要送上 CCLK 焊盘的用户时钟 |
USRCCLKTS | 输入 | CCLK 三态控制,0 = 输出使能,1 = 高阻,默认 1 |
FCSBO / FCSBTS | 输入 | FCS_B 片选输出与其三态位,语义同上(0 使能) |
USRDONEO / USRDONETS | 输入 | DONE 引脚的用户驱动与其三态位;不用就保持高阻 |
GSR / GTS | 输入 | 全局置位/全局三态,用户逻辑可主动触发全片复位或全脚高阻 |
KEYCLEARB | 输入 | 低有效,脉冲用于清除片内 AES 解密密钥 |
PACK | 输出 | PROG_USR 重配流程的编程应答,普通设计悬空 |
表里最容易写反的就是 TS 语义。Xilinx 原语沿袭的是「低有效使能」传统:USRCCLKTS=0 表示把输出缓冲器打开,USRCCLKO 才能真正出现在引脚上;写 1 则引脚高阻。很多人按「1 等于使能」的直觉写成 1,结果 SPI 控制器一切正常,Flash 端却量不到时钟,排查半天。FCSBTS、USRDONETS 全是同一口径。
下面是一份概念性的最小例化,省略了真实工程里的时钟生成与 SPI 控制状态机,只展示接管关系:
STARTUPE2 #(
.PROG_USR("FALSE"), // 不使用用户发起的 PROG 重配流程
.SIM_CCLK_FREQ(0.0) // 仿真参数,按原语模板说明设置
) u_startupe2 (
.CFGCLK (), // 内部配置时钟,一般悬空
.CFGMCLK (),
.EOS (eos), // 启动结束标志,交给用户逻辑
.CLK (1'b0), // 启动时钟未选 User 时接地
.GSR (1'b0),
.GTS (1'b0),
.KEYCLEARB (1'b1), // 不清密钥,保持高
.PACK (),
.USRCCLKO (spi_sclk), // 待送上 CCLK 的时钟
.USRCCLKTS (cclk_ts), // 0=输出使能;EOS 后才允许拉低
.USRDONEO (1'b1),
.USRDONETS (1'b1), // DONE 脚保持高阻,交回外部上拉
.FCSBO (spi_csn), // Flash 片选
.FCSBTS (fcsb_ts) // 同样 0 才使能
);还有一个必须澄清的混淆点:DIN/DOUT(即主 SPI 模式下的 D01/MISO 与 D00/MOSI)并不经过 STARTUPE2。它们是「双重用途脚」而非纯专用脚——启动结束后,只要比特流里没有打开 Persist(保持配置接口)选项,它们默认就变回普通用户 I/O,在 XDC 里按普通管脚约束、在 RTL 里直接连接即可。真正必须走原语的只有 CCLK 和 FCS_B 这两只纯专用脚。所以在线烧录的接法永远是「时钟片选走 STARTUPE2,数据走普通 IO」的混合形态。
三、CCLK 交接时刻:一段值得画出来的握手
把接管时刻沿时间轴摊开,信号关系如下。配置期 CCLK 由配置状态机驱动;DONE 释放、启动序列走完后 EOS 拉高;用户逻辑检测到 EOS,先让 USRCCLKO 输出稳定时钟,再把 USRCCLKTS 从默认的 1 拉低,CCLK 焊盘从高阻切到跟随用户时钟。
读这张波形抓三个阶段:前五拍配置状态机通过 CCLK 给 Flash 发读取时钟,引脚就是配置时钟;DONE 先释放、EOS 随后拉高,此时配置电路停车,而 USRCCLKTS 还停在默认值 1,所以中间两拍引脚进入高阻(图中 z 段);用户逻辑在 EOS 之后先把 USRCCLKO 跑起来,再把 TS 拉低,引脚从第八拍起改随用户时钟翻转。工程上常见的稳妥写法是用 EOS 同步释放一个「接管允许」标志,TS 位在该标志为 1 且用户时钟已经稳定若干拍后才拉低,避免引脚出现半截时钟沿。
值得一提的是,Xilinx 的 AXI Quad SPI 等官方 Flash 控制器 IP 提供了「使用 STARTUPE2」的选项,勾选后 IP 内部已经按这套时序处理好时钟相位(通常经 ODDR 沿对齐转发)与三态衔接;自己手写控制器时,时钟沿对齐和 TS 时序要以 IP 实现或原语手册为参照,不要凭感觉调延时。
四、头号场景:启动后反过来给配置 Flash 烧镜像
EOS 之后 FPGA 已经是一块跑着你设计的普通芯片,而板上那颗 QSPI/BPI Flash 还挂在原处。通过 STARTUPE2 接管 CCLK 与 FCS_B、用普通 I/O 驱动 D00/D01,FPGA 就从「Flash 的客户」变成「Flash 的主机」,可以发任何 SPI 命令:读 JEDEC ID、整片擦除、页编程、回读校验。
这张拓扑图的看点是两条方向相反的路径:上电时箭头从 Flash 指向 FPGA,它是启动源;启动后擦写链路反过来,FPGA 成为主设备。橙色是执行擦写的用户侧逻辑,蓝色 D00/D01 走普通布线,灰色 STARTUPE2 是专用脚的唯一通道,数据脚与时钟片选在 Flash 焊盘处汇合。容量怎么算、选 QSPI 还是 BPI 见配置 Flash 容量怎么选。
在线烧录有四个工程纪律,任何一条破了都可能把设备变成砖:
- 擦写期间绝不能掉电。Flash 按扇区擦、按页写,中途断电会留下半个镜像,下次无法启动。系统要保证供电裕量,擦写窗口内屏蔽低电告警路径。
- 写完必须回读校验。页编程之后读回逐字节比对(或利用 Flash 的 CRC/安全寄存器),校验不过则重试或报错,不能「发完就算成功」。
- 黄金镜像 + 硬件写保护。Flash 划分 golden 区与 update 区,golden 区接 Flash 的 WP# 保护或锁保护寄存器;即使新镜像损坏,golden 仍可启动。双区布局与 fallback 机制见 FPGA 在线升级与 multiboot。
- 时钟频率遵守 Flash datasheet。接管后的 CCLK 来自用户时钟,不能因为「内部时钟跑得快」就超频;老型号 Flash 的擦写指令时钟上限往往低于读取上限。
校验通过后,让新镜像生效有两种方式:外部给 PROGRAM_B 一个低脉冲做冷重配,或由 FPGA 内部经 ICAP 发起 warm boot 跳转到新地址(后者正是 multiboot 篇的主题)。
五、DONE / INIT_B / PROGRAM_B:不止是指示灯
STARTUPE2 还给了用户逻辑接触 DONE 脚的通道,而 INIT_B、PROGRAM_B 虽然没有对应的原语驱动口,却经常和板级复位、重配控制打交道。三只脚的电气特性完全不同,混用是常见的硬件设计错误。
| 引脚 | 电气类型 | 谁在驱动 | 启动后的典型用途 |
|---|---|---|---|
| DONE | 开漏,必须外部上拉 | 配置末期 FPGA 释放;USRDONEO 可由用户逻辑驱动 | 状态指示、释放外设使能;经 USRDONETS 可参与握手 |
| INIT_B | 开漏,双向 | 清空/CRC 错误时 FPGA 拉低;外部也可拉低推迟配置 | 配置错误告警、外部器件延迟 FPGA 启动 |
| PROGRAM_B | 专用输入,带上拉 | 只由外部驱动(按键、监控芯片、另一颗 MCU) | 低脉冲触发整机重新配置,等效于「重启 FPGA」 |
三点展开。第一,DONE 是开漏脚,板上没有上拉电阻就永远不会变高,现象是配置看似完成、DONE 灯却不亮;多芯片级联同步启动时,几颗 FPGA 的 DONE 常线与在一起,等所有器件都加载完才共同释放。如果让用户逻辑经 USRDONEO 驱动它,务必想清楚和外部上拉、其它芯片的线与关系,没事不要接管,USRDONETS=1 保持高阻是最常见选择。
第二,INIT_B 是双向开漏,有两个方向的用法:FPGA 在清空阶段拉它、CRC 出错时也拉它(所以「INIT_B 启动后被拉低」基本等于配置数据错误);外部器件在电源或时钟未就绪时拉低它,则能推迟配置开始。运行期用户逻辑一般不直接驱动它,但可以通过配置状态寄存器读取其状态来判断启动是否干净。
第三,PROGRAM_B 只能从外部拉低,STARTUPE2 没有它的驱动端口。板上常见接法是一个按键加一个监控 MCU 的 I/O:FPGA 跑飞时看门狗给一个低脉冲,强制重新加载。注意脉冲宽度要满足数据手册的最小值要求,且它是异步重配,片内当前状态全部作废——想从 FPGA 内部主动重启,走 ICAP warm boot,不要试图在内部「找 PROGRAM_B」。这些信号在启动时间轴上出现的先后,可对照上电配置时序篇的 DONE→GTS→GWE→EOS 顺序阅读。
六、什么时候必须用,普通 IO 什么时候就够
最后给一个决策表,省得在简单需求上过度设计。
| 你的需求 | 需不需要 STARTUPE2 | 说明 |
|---|---|---|
| 在线擦写启动用 SPI/BPI Flash | 必须 | CCLK、FCS_B 是纯专用脚,无第二条通路 |
| 用逻辑驱动/监视 DONE,或多 DONE 线与握手 | 需要 | 经 USRDONEO/USRDONETS |
| 用用户时钟作为启动序列时钟源 | 需要 | CLK 输入配合比特流启动时钟选项 |
| 运行期使用 D00/D01(MOSI/MISO)接外设 | 不需要 | 双重用途脚,启动后默认是普通 IO |
| 普通 GPIO、UART、自定义外设 | 不需要 | 与配置电路完全无关 |
| FPGA 内部主动重启自己 | 不用原语 | 走 ICAP warm boot / IPROG |
| 外部按键或看门狗重启 FPGA | 不用原语 | 直接脉冲 PROGRAM_B |
迁移到 UltraScale / UltraScale+ 平台时,原语改名为 STARTUPE3,思路完全一致:EOS 交权、TS 位低有效逐脚接管。主要差异是 UltraScale 把 SPI 数据脚 D00–D03 的输入输出与三态也收进了原语统一管理(端口数量更多,还覆盖 x4 数据通路),不再像 7 系那样数据脚纯走普通 IO。因此从 7 系移植在线烧录代码时,数据通路部分必须按 STARTUPE3 的端口重接,不能只改个原语名。具体端口名以目标器件的 Vivado 原语模板为准。
初学者最常踩的三个坑集中收尾:一是 TS 位按高有效写,Flash 没时钟;二是没等 EOS 就接管,撞上配置电路还没完全停车;三是试图在 RTL 里直接 assign CCLK = ...,然后发现这只脚在管脚约束里根本选不到——它不在通用 I/O 列表里,只能从原语走。
这一篇在知识体系里的位置
本篇属于 FPGA 配置与启动专题中「启动之后」的一环,向上承接启动的时间轴,向下对接在线升级工程:
- 启动时序全貌(电源、POR、DONE、GTS/GWE、EOS 的先后):FPGA 上电配置时序
- 配置模式与专用脚分工(JTAG / 主 SPI / BPI / SelectMAP):FPGA 配置方式有哪几种
- JTAG 下载与 QSPI 固化的基础操作:比特流下载与固化
- Flash 容量与配置时间估算:配置 Flash 容量怎么选
- 双区黄金镜像、fallback 与 ICAP warm boot:FPGA 在线升级与 multiboot
- 启动后用户侧复位与时钟的衔接:FPGA 时钟与复位设计入门
总结
STARTUPE2 启动原语是 7 系 FPGA 专用配置脚在启动后的唯一复用通道:EOS 拉高只代表配置电路交权,USRCCLKTS/FCSBTS/USRDONETS 拉低才真正把用户信号接上引脚,三态位一律「0 使能」;在线烧录 SPI/BPI 启动 Flash 是它的头号场景,时钟片选走原语、D00/D01 走普通 IO,擦写期防掉电、写完回读、golden 区写保护三条纪律缺一不可;DONE 与 INIT_B 是开漏脚、PROGRAM_B 只接受外部脉冲,UltraScale 平台对应 STARTUPE3、数据脚也归原语统管。