FPGA 上电配置时序:从电源爬升、POR 到 DONE 与 GTS/GWE 启动序列全解
按下电源开关到第一个 LED 按你的设计闪烁,中间大约只有几十到几百毫秒。但在这段时间里,SRAM 工艺的 FPGA 并不是「通电就开始跑逻辑」——它体内上亿个配置位还是随机值,必须先按一条严格的时间轴把自己搭出来:电源爬升、上电复位、清空、采样模式、读入比特流、校验、释放 I/O、释放触发器。本篇讲的就是这条时间轴。姊妹篇 FPGA 配置方式有哪几种回答的是「配置数据从哪来、走哪几根脚」的空间问题,本篇回答「先发生什么、后发生什么」的时间问题;操作层面如何把镜像烧进 Flash 见 FPGA 入门 32:比特流下载与固化。
这张编号流程卡是全篇的地图。读它抓住一个要点:前五个阶段是「把配置数据搬进芯片」,后两个阶段是「让芯片开始工作」,DONE 是两段之间的界碑。板子上 DONE 灯不亮,说明问题在搬运阶段;DONE 亮了但行为异常,问题才在启动阶段。下面按这条主线逐段拆开讲。
本文要回答的问题
- 上电瞬间 VCCINT、VCCAUX、VCCO 三路电源必须按什么顺序爬升,POR 电路在等什么条件?
- INIT_B 和 PROGRAM_B 这两根开漏脚各自在什么时刻被拉低,清空阶段芯片内部在做什么?
- 模式脚在哪个时间点被采样,比特流开头的 dummy 字和同步字为什么不能省?
- DONE 拉高之后用户逻辑并没有立刻跑,GTS、GWE、EOS 三个启动事件按什么顺序释放,顺序和启动时钟在哪里配置?
- INIT_B 一直低、CRC error、DONE 不高三类典型失败,分别卡在哪一阶段,该先量哪个信号?
一、电源爬升与 POR:一切从电压越过门限开始
FPGA 不是单电源器件。即使最小的器件也至少有三类电源轨:核心轨 VCCINT 给内部可编程逻辑和配置存储器供电,辅助轨 VCCAUX 给 I/O 辅助电路、配置逻辑和部分块 RAM 供电,I/O 轨 VCCO 按 Bank 独立供电,决定每个 Bank 的接口电平。规模更大的器件还有 BRAM 专用轨、收发器轨等,具体轨名与电压随器件族变化,应以对应器件的数据手册和配置用户指南为准。
| 电源轨 | 供电对象 | 上电阶段的角色 |
|---|---|---|
| VCCINT | 核心逻辑、配置 SRAM(CRAM) | POR 判定的主信号;未稳前配置逻辑保持复位 |
| VCCAUX | I/O 辅助电路、配置/时钟电路 | 必须在配置开始前稳定;多数器件族要求不晚于 VCCINT |
| VCCO(每 Bank) | I/O 输出驱动、配置 Bank | 配置 Bank 的 VCCO 必须与配置接口电平一致,否则读不到数据 |
| 其它专用轨 | BRAM、收发器、PLL 等 | 随器件族增加,门限与顺序查对应配置指南 |
为什么不能三路电随便一起冲?一是器件保护:跨电压域之间有电平移位和 ESD 保护通路,I/O 轨先于核心轨建立时,外部电压可能经保护二极管反向灌入未上电的核心,产生闩锁(latch-up)风险,电源设计上的讨论见 FPGA 电源与散热设计入门。二是状态机确定性:配置逻辑必须在一个电源全部有效的起点出发,否则某个触发器的初值是随机的,后面整条时序链都不可信。
承担这个「确认全部有效」职责的是片上的 POR(Power-On Reset,上电复位)电路。它监测各电源轨是否越过规定门限并保持稳定:爬升期间 POR 有效,整片配置逻辑被按住不动;当所有被监测轨都达到门限、经过一段内部定时后,POR 才释放,配置状态机进入下一阶段。POR 是纯硬件、不可配置的——你能做的是保证电源爬升斜率、门限裕量和顺序满足器件手册的推荐窗口。冷启动偶发失败、反复上电才能起,第一嫌疑往往就是某路电在门限附近徘徊,POR 释放时电源其实还没真正稳。
二、INIT_B 拉低与清空:把上亿个配置位先写成已知值
POR 释放后,芯片做的第一件事不是读 Flash,而是清空。配置状态机主动把 INIT_B 引脚拉低,进入清空阶段:对全部配置 SRAM 逐位写入约定的初始内容,把 LUT 真值表、布线开关、I/O 配置位全部置于已知态。这个过程需要若干毫秒量级的时间(随器件容量增长),期间 INIT_B 一直保持低电平,外部电路看到 INIT_B 为低,就知道芯片还没准备好接收数据。
这里要分清两根名字相近、都是低有效、都是开漏的脚:
| 引脚 | 谁拉低 | 含义 | 释放后 |
|---|---|---|---|
| PROGRAM_B | 外部按键/主控,或芯片内部 | 请求重新开始一次完整配置 | 芯片检测到上升沿后重新进入清空 |
| INIT_B | 芯片自己(开漏,可外部观察) | 正在清空;配置中出错时也会拉低报错 | 变高表示清空完成,可以送配置数据 |
清空完成后 INIT_B 释放为高(开漏脚通常需要外部上拉)。这个上升沿也是外部主控在从模式下开始喂数据的握手信号——主控必须等 INIT_B 变高才能发第一个时钟沿,提前发的数据直接丢弃。理解到这一层就能解释一个常见现象:上电后 INIT_B 长时间为低,不一定是芯片坏了,可能是 PROGRAM_B 被外部器件误拉住、清空被反复重启,也可能是某路电源没过 POR 门限导致清空阶段根本没开始。
三、模式采样与同步字:状态机在哪里「分叉」
INIT_B 变高前后的一个规定时刻,配置逻辑采样模式引脚(Xilinx 器件族常见为 M[2:0],Intel 器件族为 MSEL),决定这次配置走哪条入口:JTAG、主串/SPI、主并/BPI 还是从口。模式脚的接法决定了谁发配置时钟(CCLK)、数据走串行还是并行,五种模式的接线与适用场景在 FPGA 配置方式有哪几种里有完整对比。采样只发生在这一瞬间,且引脚电平在采样窗口内必须稳定——用跳线或拨码开关设模式时,如果开关抖动或被其它器件争抢,芯片会按一个错误的模式出发,表现为从口模式下怎么喂数据都没有反应。
模式定下来之后,主模式下 FPGA 开始自己驱动 CCLK,从外挂 Flash 取数据;从模式下则等外部主控发时钟。无论哪种入口,比特流的开头都不是有效配置数据,而是两类引导字段:
- dummy 填充字:若干个全 0 或约定格式的空拍,给时钟和接口留出稳定时间,同时让内部流水线对齐;
- 同步字:一个固定的特殊 32 位模式(常见为
0xAA995566,随厂商/器件族不同),配置状态机在串行位流里一旦对齐到这个字,就确立了后续数据的字边界。
同步字之前的任何位都被无视,同步字之后数据才按「写配置寄存器命令 + 数据帧」解释。这个设计解决的是串行通信的经典问题:接收方上电时不知道位流从哪里开始算第一个字,必须靠一个不可能在正常数据里误判的定界图案重新对齐。同步字写错(比如手工拼接镜像、用错字节序或位序)时,状态机永远等不到同步,现象就是 CCLK 在转、Flash 在读,但 DONE 毫无动静。
下面这张流程图把前面三段到帧写入的主干画在一起,颜色区分角色:蓝色是入口与等待条件、橙色是芯片执行的动作、绿色是通过/完成,CRC 失败的红色回路边表示出错后状态机会拉低 INIT_B、退回清空重来。
读这张图抓住主干一条线、回环一条线:主干是蓝色条件推动橙色动作、最终到绿色完成;回环是帧写阶段一旦校验失败,状态机不进入 DONE,而是沿红色边退回清空,整个配置重新开始——这就是为什么 CRC 错误时用示波器会看到 INIT_B 周期性出现低脉冲。
四、帧写入与 CRC:配置数据怎样落进配置位
同步之后进入配置数据传输的主体。比特流不是一坨无结构的二进制,而是按「帧(frame)」组织的:帧是配置数据寻址的最小单位,每一帧对应芯片中一段配置位区域,帧地址由配置状态机内的一组配置寄存器(如帧地址寄存器、命令寄存器、控制寄存器)解释。典型的数据流是一串总线命令:写命令寄存器指定操作、写帧地址寄存器指定位置、写若干帧数据、再发一条 CRC 校验命令。比特流由工具自动生成这些命令序列,比特流下载与固化展示的 .bit 到 Flash 镜像的转换处理的就是这一层封装。
每写入一批帧,比特流会要求状态机对累计数据做一次 CRC(循环冗余校验)。CRC 覆盖从同步字之后到当前的全部命令与数据,芯片算出的值必须和比特流中携带的期望值一致:
- 一致:状态机继续处理下一命令;
- 不一致:状态机立即在 INIT_B 上输出一个低脉冲(开漏),终止本次配置,按器件行为重试或停在错误态等待外部重新发起。
CRC 防的是传输通道错误,不是设计错误——Flash 焊接虚连、SPI 时钟频率超过器件在该电压下的上限、信号完整性差、镜像烧录错位,都会让「Flash 里存的」和「芯片收到的」不一致。所以排查 CRC 错误的方向永远在通道侧:降 CCLK 频率、查走线和上拉、核对镜像字节序,而不是去改 RTL。顺带一提,比特流加密保护的是「Flash 内容被读出来抄板」的问题,它工作在帧写入之前的解密环节,与 CRC 是两条独立机制,簇内后续会有专文介绍。
五、DONE 与启动序列三巨头:为什么 DONE 亮了逻辑还没跑
全部帧写入、最终 CRC 通过后,状态机执行最后几条命令,其中最显眼的是释放 DONE 引脚。DONE 是开漏输出,需要外部上拉;它一拉高,板子上的 DONE LED 点亮,外部主控也据此知道「配置数据已经完整、正确地进入芯片」。很多资料把 DONE 拉高描述为「FPGA 启动完成」,这不精确——DONE 只是进入启动序列(Startup Sequence)的门票。
启动序列是配置状态机最后的一段节拍化流程,包含三个必须按顺序释放的全局控制信号:
| 信号 | 全称含义 | 释放前 | 释放后 |
|---|---|---|---|
| GTS | Global Tri-State,全局三态 | 全部用户 I/O 强制高阻 | I/O 按设计成为输入/输出,引脚开始受控 |
| GWE | Global Write Enable,全局写使能 | 全部触发器保持、不可翻转,等效全局复位 | 时钟沿可以写入触发器,时序逻辑开始运转 |
| EOS | End Of Startup,启动结束标志 | 状态机仍在配置态 | 标记配置全流程结束,部分接口交还用户 |
典型释放顺序是 DONE → GTS → GWE:先让 I/O 脱离高阻,再让触发器开始翻转,这样用户逻辑第一次「活过来」时它驱动的引脚已经具备输出能力,避免内部 FF 已经翻转、输出却还关在三态里造成的毛刺窗口。EOS 之后配置接口的行为也随选项而定——可以释放给用户当普通 I/O 使用,也可以保持以便回读。组合逻辑在 GTS 释放后就开始输出(它没有时钟概念),时序逻辑则要等 GWE 释放后的第一个有效时钟沿——这就是「DONE 亮了再过一会儿逻辑才动」的根因。复位与时钟在用户逻辑侧的衔接可参考 FPGA 时钟与复位设计入门。
DONE、GTS、GWE 各自排在启动序列的第几拍,并不是焊死的:工具里允许配置这些事件的节拍位置,以适配需要多颗 FPGA 同步启动(用 DONE 线与互相等待)等特殊板级场景。单器件应用用默认顺序即可,但要知道「顺序可调」这件事——多 FPGA 板互相等待 DONE 却死锁时,问题往往就在启动事件的节拍配置上。
六、启动时钟与启动列:启动序列用谁的节拍走
启动序列的每一拍都需要时钟沿,这个时钟可以选,是上电配置时序里少数留给用户的关键选项:
| 启动时钟选项 | 来源 | 适用与注意 |
|---|---|---|
| CCLK | 配置时钟(主模式由 FPGA 内部振荡器分频产生) | 默认选项;配置结束后仍有节拍,最省心 |
| USERCCLK | 用户设计提供的时钟(经专用启动时钟引脚/网络送入) | 用户逻辑时钟与启动节拍同源,可让 GWE 释放与逻辑时钟精确对齐;但配置结束时此时钟必须已经稳定存在,否则启动序列会停住 |
| JTAG(TCK) | JTAG 口直接下发启动 | 调试场景;JTAG 发起的配置用 TCK 走完启动节拍 |
USERCCLK 是新手最容易踩的选项:它通常来自用户设计里的晶振经 PLL/MMCM 处理后的时钟,而 GWE 释放前用户触发器全部保持,PLL 在配置完成前也未工作——必须选用一条在配置阶段就存在的时钟通路(如直接引外部晶振),启动序列才有节拍可走。现象很典型:CRC 全过、DONE 已高,但整个芯片停在那里,I/O 不活、逻辑不跑,示波器量启动时钟发现根本没有沿。默认 CCLK 可以避开这个鸡生蛋问题;只有在多芯片启动同步、或需要 GWE 与特定时钟沿对齐时才换 USERCCLK。
启动序列的「列顺序」(各事件排在哪一拍)和启动时钟在工程属性里设置,随工具链不同叫法不同(比特流/配置属性中的 Startup Clock、启动时序选项等)。改这类属性后必须重新生成比特流——启动列是写进比特流命令序列的,不是运行时寄存器。在线升级(multiboot/黄金镜像回退)场景还会用到热启动入口,跳过重清空直接加载另一镜像,属于本机制的进阶变体,簇内后续会有专文。
下面这张波形图把六根关键信号的相对时序画在一条时间轴上:PROGRAM_B 一个低脉冲触发重配,INIT_B 拉低覆盖清空期,INIT_B 释放后 CCLK 与数据才开始活动,全部帧写完后 DONE 才拉高,GTS/GWE 在 DONE 之后的启动节拍里依次释放。
读这张图抓三段:第一段 INIT_B 低、时钟死,芯片在清空;第二段时钟翻、数据流,芯片在搬运配置;第三段 DONE 高之后没有数据了,但启动节拍仍在走,GTS/GWE 在这段里释放。现场拿示波器量这五根脚,看波形停在哪一段,就知道配置卡在哪一关。
七、典型上电失败的时序定位
把前面机制反过来用,就是排查方法:先定位「时间轴停在哪一阶段」,再查该阶段的条件。下表把三类最常见现象与阶段对应起来。
| 现象 | 停住的阶段 | 首查方向 |
|---|---|---|
| INIT_B 一直为低,从不释放 | POR 或清空 | 量三路电源是否过门限;PROGRAM_B 有无被外部拉住;模式脚与配置 Bank 的 VCCO |
| INIT_B 释放但 DONE 永远不高 | 同步或帧写入 | 模式脚采样电平;SPI/并口线序与上拉;降 CCLK;镜像字节序/同步字是否正确 |
| INIT_B 周期性低脉冲 | CRC 校验失败回退 | Flash 焊接与虚连;CCLK 频率上限;信号完整性;镜像是否烧在正确偏移 |
| DONE 已高但 I/O 不工作 | 启动序列 GTS | DONE 引脚外部上拉是否装对;启动事件节拍配置 |
| DONE 已高、I/O 活但时序逻辑不跑 | 启动序列 GWE | 启动时钟选项:USERCCLK 是否在配置后仍有沿;用户复位/锁相环锁定信号 |
| 偶尔能启动偶尔不能 | 电源时序临界 | 电源爬升斜率与裕量;CCLK 余量;温度相关性 |
排查路径按漏斗收敛:先看电源级,再看清空握手,再看数据通道,最后看启动事件,不要一上来就怀疑比特流坏了。下图把这张分诊逻辑整理成思维导图,现场可以从上到下逐级排除。

这张思维导图的使用方式是「逐级排除、不越级」:电源级任何一项不满足,下面三级都无从谈起;只有确认 INIT_B 能正常释放,才值得花时间查模式脚和 CRC;只有 DONE 确实拉高,GTS/GWE 的讨论才有意义。配合示波器或逻辑分析仪同时抓 PROGRAM_B、INIT_B、CCLK、DONE 四根脚,再用上板调试手段观测内部状态,大多数「上电不起」可以在一小时内定位到级,板级 bring-up 的通用方法见 FPGA 板级 Bring-up 与调试方法,固化链路的专门排查见 FPGA 掉电不启动怎么排查,仿真通过而上板行为异常的区分见 仿真通过但上板不工作。
这一篇在知识体系里的位置
本篇属于 FPGA 配置机制簇的「时间轴」分支,与以下已发布文档配套阅读:
- FPGA 配置方式有哪几种:同一簇的「空间轴」——JTAG/SPI/SelectMAP/BPI 谁发时钟、走哪几根脚;
- FPGA 入门 32:比特流下载与固化:操作向,如何把镜像下载并写进 Flash;
- FPGA 电源与散热设计入门:电源轨设计、爬升顺序与闩锁风险的硬件视角;
- FPGA 掉电不启动怎么排查:本篇第七节的排错短答版,聚焦固化链路;
- FPGA 时钟与复位设计入门:GWE 释放后用户逻辑侧的复位与时钟衔接;
- FPGA 板级 Bring-up 与调试方法:上板调试的完整方法论。
同簇后续规划的比特流加密、在线升级与 multiboot 两篇,分别对应本篇帧写入前的解密环节与热启动变体,发布后将在此处补链。底层架构背景(CRAM 为什么掉电丢失)可回顾 FPGA 架构与工作原理。
总结
FPGA 上电配置时序是一条由片上状态机固化的七段时间轴:电源轨依次爬升并越过 POR 门限后,芯片拉低 INIT_B 清空全部配置 SRAM;INIT_B 释放瞬间采样模式脚,在 CCLK 或外部时钟下先吃 dummy 与同步字对齐字边界,再按帧把比特流写进 CRAM 并逐段 CRC 校验;校验失败会拉低 INIT_B 退回重来,全部通过才释放 DONE;DONE 之后启动序列仍按 DONE→GTS→GWE 的节拍顺序释放 I/O 三态和触发器写使能,用户逻辑至此才真正苏醒,而启动节拍用 CCLK 还是 USERCCLK、各事件排在哪一拍,都在比特流属性里预先约定。排查启动失败只需判断波形停在电源、清空、加载、启动哪一级,再查该级对应的条件即可。