FPGA复位设计:异步复位同步释放与PLL复位避坑 简介围绕 Verilog 与 FPGA 设计中复位机制展开的专题文档面向需要厘清同步复位、异步复位及同步释放差异的硬件工程师与学习者重点解决复位信号撤销时的亚稳态、资源占用和 PLL 配置时序问题。压缩包内共 1 个 docx 文件大小约 217KB便于直接查阅与整理笔记。已有 2369 人学习下载说明该主题在工程实践中有较高关注度。文档结合代码片段与综合后的 RTL 视图对比异步复位专用 CLRN 端口、同步复位额外逻辑资源消耗以及两级寄存器异步复位在建立/保持时间边界出现的不同步风险并给出异步复位、同步释放的层叠寄存器实现思路。对 PLL 配置复位设计文档强调在外部时钟 clk 与输入复位 rst_n 完成异步复位、同步释放后送入 PLL使 PLL 时钟有效输出前系统其他部分保持复位帮助读者理解多时钟系统中的稳定复位方案与设计取舍。1. 复位真正的风险不在“拉低”而在“松开”很多人写下always (posedge clk or negedge rst_n)的那一刻会默认复位是一件“立刻、彻底、同时”发生的事。真实情况恰好相反复位有效的那一瞬间确实干脆利落但复位撤销的那一瞬间才是整个设计最脆弱的地方。同步复位、异步复位、异步复位同步释放这三种写法差别几乎全部集中在复位信号由低变高的那几个纳秒里。异步复位把信号直接接到 FPGA 寄存器的专用清零端 CLRN省资源、不依赖时钟代价是撤销时刻完全不受时钟约束同步复位把复位降级成数据通路上的一级逻辑干净但要多花 LUT而且时钟没起来就彻底失灵异步复位同步释放把“有效”和“撤销”拆成两条路径分别处理用两个触发器换一个确定的释放时刻。把这三者的分野搞清楚本质上是搞清楚一个异步信号跨进时钟域时到底发生了什么——这也是后面 PLL 复位设计绕不开的前提。2. 异步复位与同步复位综合之后复位信号究竟走了哪条路写代码时两者只差敏感列表里多一个negedge rst_n但综合器给出的电路结构完全不同一个走寄存器的专用控制端口一个走数据通路的组合逻辑。这个差别决定了后面所有的资源开销、时序约束和失效模式。2.1 异步复位为什么最后都落到寄存器的 CLRN 端口module async_rst_demo ( input wire clk, input wire rst_n, // 低电平有效 input wire din, output reg q ); // 敏感列表里同时列出时钟沿和复位沿综合器据此判定为异步控制 always (posedge clk or negedge rst_n) begin if (!rst_n) q 1b0; // 不依赖 clkrst_n 一拉低立即执行 else q din; end endmodule这段代码综合之后q的 D 端只接din复位那条路径直接进了寄存器的 CLRN异步清零端。这里有一个新手常困惑的点如果代码里写成高电平有效if (rst)综合出来的 CLRN 依然是低有效工具会自动在复位路径上插一个反相器把极性掰回来。也就是说你写的极性是你的事CLRN 的极性是器件的事中间那级反相器不会省。这条路带来的好处很实在。第一它不依赖时钟上电瞬间、晶振还没起振、PLL 还没锁定的时候异步复位照样能把寄存器按在复位态这是同步复位做不到的。第二它几乎不消耗额外的组合逻辑资源因为 CLRN 是触发器自带的硬件端口复位信号从引脚一路走到 CLRN中间理想情况下不需要任何 LUT。第三复位脉冲再窄也能被捕获只要满足 removal 时间哪怕只有一个纳秒的低电平也能生效而同步复位要求复位至少维持一个完整时钟周期并被采样到。代价同样明确。异步复位对毛刺是绝对敏感的——复位线上任何一个窄毛刺都会被当成一次真正的复位寄存器直接被清零而这类故障在仿真里基本抓不到。更麻烦的是撤销时刻rst_n由低变高和clk上升沿之间没有任何约定关系这个异步的“松开”动作会在第 3 章里引出大问题。2.2 同步复位复位信号被降级成一路普通数据module sync_rst_demo ( input wire clk, input wire rst_n, // 低电平有效 input wire din, output reg q ); // 敏感列表只有时钟沿综合器认为复位是数据通路的一部分 always (posedge clk) begin if (!rst_n) q 1b0; // 只有 clk 上升沿到来时才可能生效 else q din; end endmodule综合之后CLRN 端悬空不用了q的 D 端变成rst_n ? din : 1b0落到电路上就是一个与门或者一个二选一多消耗一级 LUT。如果这个复位要驱动上千个寄存器工具不会真的给你画一千个与门它会做扇出复制、把复位信号拆成多份但逻辑层级该有还是有——复位信号从此变成了一根高扇出的数据信号要和真正的数据争抢 LUT 输入端口。在输入端本就紧张的小容量器件上这一级 LUT 的代价并不便宜。同步复位换来的好处是干净。窄于一个时钟周期的毛刺根本采不到复位线天然具备滤波效果复位撤销一定发生在时钟沿上所有寄存器在同一个沿一起退出复位不存在“有的醒了有的还睡着”时序分析时它被当成普通数据路径只需要看 setup/hold不必额外做 recovery/removal 检查。但它有两个很难绕过去的限制。第一时钟必须已经在跑。凡是时钟门控、低功耗停振、PLL 未锁定、上电初期晶振未稳的场景同步复位全部失效系统会卡在复位态出不来——这是很多“上电后按键复位也没反应”的直接原因。第二复位脉冲宽度必须大于一个时钟周期且恰好被采到如果复位源是机械按键或者上电复位电路给出的窄脉冲就得自己做展宽。2.3 一张表看清两种写法的取舍维度异步复位同步复位综合后落点触发器专用 CLRN 端口数据通路的与门/二选一额外逻辑资源几乎为零每个复位寄存器多一级 LUT是否需要时钟不需要必须有时钟在跑时钟停止时能否复位能不能毛刺敏感度极高任何毛刺都触发复位低窄于一周期的毛刺被滤掉复位释放异步可能与时钟沿重合与时钟沿对齐时序检查项recovery / removalsetup / hold上电初期可用性可用不可用单看这张表异步复位几乎是压倒性优势省资源、不依赖时钟、上电就能用。也正因为如此很多项目里always (posedge clk or negedge rst_n)被当成默认写法一路铺下去直到板子上出现那种“跑几个小时才挂一次、仿真永远复现不了”的故障才回头审视复位撤销那一下。3. 复位撤销瞬间两级寄存器为什么会走出两种状态真正的问题不在复位有效期间而在它失效的那一个时刻。把两个寄存器串起来看问题会暴露得非常清楚。3.1 recovery 与 removal异步复位也有自己的建立保持窗口// 两级流水共用同一个异步复位 always (posedge clk or negedge rst_n) begin if (!rst_n) b 1b0; else b a; end always (posedge clk or negedge rst_n) begin if (!rst_n) c 1b0; else c b; end复位有效时b和c的 CLRN 同时被拉低两个寄存器都清零看起来无比同步。问题出在rst_n由低变高的那一刻。异步复位端口并不是“随时松开都没事”的。它有自己的时序窗口recovery time要求复位释放到下一个有效时钟沿之间留出最小间隔作用类似 setupremoval time要求时钟沿之后复位还得保持一小段时间作用类似 hold。这两个参数在器件手册里通常不显眼但只要复位释放落进了这个窗口寄存器的输出就会进入亚稳态——电平既不是稳定的 0 也不是稳定的 1而是一个会在中间电平附近徘徊、靠噪声才能最终定下来的状态恢复时间还是个概率问题。关键在于b和c虽然是同一个模块、同一根rst_n但它们的 recovery/removal 余量并不相同。布线长度不一样、时钟偏斜skew不一样、两个触发器在 die 上的物理位置不一样导致同一个复位撤销沿到达两个 CLRN 的时刻存在皮秒到纳秒级的差异。物理上就不存在“同时松开”这回事。3.2 一根 rst_n 松开时四种结局里有两种是灾难假设rst_n的上升沿正好落在某个时钟沿的 recovery/removal 窗口内此时clk采到的rst_n状态是不确定的于是可能出现四种组合b的状态c的状态后果复位0复位0正常下一拍一起开始工作释放正常释放正常正常一起退出复位复位0释放正常前后级状态不一致释放正常复位0前后级状态不一致前两种是安全的后两种才是真正的隐患。想象一条状态机前级已经退出复位、跳到 IDLE后级还压在复位态输出全零或者反过来后级已经醒了前级还在清零把刚算出来的数据打成 0。再想象一个计数器高位寄存器的 CLRN 先松开低位还压着下一拍计数值直接从 0 跳到 128——在仿真里这个初值错误会一路传下去最后表现成外设配置写错、DMA 描述符地址错位、通信帧头对不上。单个两级流水出问题你还能靠波形抓放到一个几万寄存器的大项目里几千个寄存器各自以微秒级的随机差异退出复位故障就变成了概率事件温度变了、电压变了、换一批芯片现象就变了。这类问题没有后悔药只能靠结构上提前规避。3.3 同步复位为什么只是“降低概率”而不是消除看到这里很容易得出一个结论那就全用同步复位。但同步复位只是把问题换了个位置并没有消灭它。同步复位把rst_n降级成数据采样窗口从 recovery/removal 变成了 setup/hold。如果rst_n本身与clk是异步的外部按键、上电复位芯片输出、另一个时钟域产生的复位它照样可能违反 setup/hold照样让那个寄存器输出亚稳态。区别只在于亚稳态被限制在单个寄存器上而且下一拍就会被新的数据覆盖掉不像异步复位那样造成多个寄存器状态分叉。但这仍然不够。第一那个亚稳态拍输出的错误值如果直接驱动了组合逻辑比如状态机的次态译码错误动作已经发出去了下一拍再恢复也来不及。第二同步复位要求时钟已经在跑上电初期和 PLL 未锁定期间完全无解。所以两条路都走不通异步复位不安全同步复位不可靠工程上的答案是第三条——异步复位同步释放。4. 异步复位同步释放把“有效”和“撤销”拆成两条路这个结构其实就是两个触发器但它的价值在于给“复位有效”和“复位失效”分配了完全不同的路径有效沿走异步快车道撤销沿走同步慢车道。4.1 复位同步器一条异步路径加一条同步路径module rst_sync ( input wire clk, input wire arst_n, // 异步复位输入低有效来自引脚或上电复位电路 output wire rst_n // 同步释放后的复位低有效送给下游所有寄存器 ); // ASYNC_REG 让工具把两级放到同一 slice 内缩短两者之间的布线延迟 (* ASYNC_REG TRUE *) reg rst_meta; (* ASYNC_REG TRUE *) reg rst_sync; always (posedge clk or negedge arst_n) begin if (!arst_n) begin rst_meta 1b0; // 复位有效走异步路径不需要时钟 rst_sync 1b0; end else begin rst_meta 1b1; // D 端恒接 1撤销时靠移位把 1 送进去 rst_sync rst_meta; end end assign rst_n rst_sync; endmodule这段代码的关键在于两个触发器的 D 端都恒接 1。复位有效时arst_n拉低两个触发器的异步清零端被直接拉低输出立刻变 0全程不需要clk参与——这就是“异步复位”的那一半保证了上电、时钟未起、PLL 未锁定这些场景下系统仍然被按住。arst_n松开时rst_meta的 D 端是 1第一拍就可能采到一个亚稳态值但rst_sync要到下一拍才去采rst_meta中间隔了将近一整个时钟周期。这段额外的时间足够让rst_meta从亚稳态里恢复成确定的 0 或 1。于是rst_sync的输出只会有两种可能这一拍释放或者下一拍释放。它可能比理想时刻晚一个周期但绝不会分叉。更关键的是扇出。所有下游寄存器看到的rst_n都是同一根网线、同一个rst_sync的输出它们的复位撤销发生在同一个时钟沿上。晚一拍不要紧整个系统一起晚一拍就行——一致性比及时性重要得多。这就是“同步释放”真正的含义不是让复位撤销变快而是让它变整齐。4.2 两级为什么够用什么时候该用三级两级同步器的可靠性可以用 MTBF 来描述第一级进入亚稳态后留给它恢复的时间约等于一个时钟周期减去布线延迟和建立时间这个时间越长未恢复的概率呈指数下降。常见的估算式是 MTBF 与e^(t_r/τ)成正比其中t_r是可用恢复时间、τ是器件的亚稳态时间常数。因为是指数关系多一级触发器带来的收益非常明显。常见的实现思路是几十到一百多兆赫兹的常规设计两级足够时钟频率推到几百兆赫兹、或者产品对可靠性要求苛刻时把同步器做到三级代价只是复位释放再晚一个周期。这个代价几乎可以忽略因为复位释放晚上几纳秒对系统行为没有任何影响。反过来说有几种写法会把这个结构毁掉需要特别留意。一是不要用组合逻辑去“优化”输出比如assign rst_n rst_meta rst_sync——这等于绕过了第二级触发器把亚稳态直接放到复位线上。二是不要在同步器输出后面再串组合逻辑去驱动 CLRN复位路径上任何组合逻辑都会引入新的偏斜把好不容易做出来的一致性又打散。三是同步器本身不能靠一个“需要时钟才能产生”的复位源来复位否则时钟没起来时整条链永远出不来复位系统死锁——这一条在下一章的 PLL 场景里会正面撞上。4.3 扇出、寄存器复制与综合属性一根rst_n驱动几千个 CLRN是典型的高扇出网络。工具的处理方式是自动做寄存器复制把你写的rst_sync复制成几十份各自驱动一片区域再把它们的输入接在一起。这个优化必须允许它发生如果为了“波形好看”强制把复位寄存器设成唯一实例综合出来的复位树会严重拥塞布线延迟差被放大反而破坏了同步释放的一致性。ASYNC_REG属性的作用是告诉工具这两个寄存器处在跨时钟域路径上不要拆分、不要重定时、不要合并并尽量放在同一个 slice 里以缩短它们之间的延迟。少写这个属性两级同步器在小规模设计里通常也能正常工作因为工具碰巧没优化它一旦设计规模上去、工具开始激进优化它被合并成一级、被搬到两个相距很远的角落故障就开始以极低概率出现——这类问题查起来最费时间。5. 避坑与排查复位问题在板子上长什么样复位相关的故障有个共同特点仿真全过、时序报告全绿、上板偶发。因为大部分问题都发生在仿真模型不建模的地方——亚稳态、复位撤销的物理偏斜、上电时序。5.1 出问题先看这三份报告第一份是时序报告里的 recovery/removal 检查项。异步复位直接进 CLRN 而不做同步释放的设计这一项通常会报出一片违例或者因为没设约束而根本没被检查——后者更危险等于问题被静默跳过。第二份是高扇出网络报告看复位网络的扇出数和延迟分布扇出过大意味着到达各寄存器的时刻差异大。第三份是综合后的寄存器被优化清单确认同步器的那两级还在、没被合并、没被重定时搬走。5.2 五条踩坑记录现象一仿真完全正常上板跑几分钟到几小时随机跑飞复位后又能正常一段时间。原因异步复位撤销没有做同步释放rst_n松开时落在某个寄存器的 recovery/removal 窗口内造成前后级状态分叉亚稳态拍把非法值灌进了状态机。 解决把所有异步复位统一改成异步复位同步释放同步器输出直接驱动 CLRN中间不加组合逻辑。改动量很小但要在项目初期就定成规范后期补是灾难。现象二时序报告里 recovery/removal 一片红但功能“看起来没问题”。原因复位路径被当成普通控制信号工具按默认约束去算而复位网络扇出大、布线长余量为负。功能没出错只是因为当前温度电压下亚稳态概率低。 解决给复位输入设成异步信号并加 false path同时用同步释放结构把真正的复位撤销交给时钟域内的同步器处理。约束不是用来“消掉报错”的是用来告诉工具哪条路径不按同步时序检查。现象三代码里明明写了两级同步器综合后只剩一级。原因缺少ASYNC_REG属性或者两级之间被工具识别成可以合并的冗余寄存器重定时时被搬走或吸收。 解决给两级都加上ASYNC_REG在综合日志里确认没有被优化掉必要时再加 preserve 类属性。这条在项目换工具版本时尤其容易翻车升级后要重新核对一次综合结果。现象四手一碰板子就复位或者电机一转就复位。原因异步复位线是纯异步路径对毛刺零免疫力干扰直接灌进 CLRN。同时复位输入没有做基本的滤波和上拉。 解决复位输入加 RC 滤波或施密特触发器PCB 上让复位线远离功率回路逻辑侧用同步释放结构吃窄毛刺必要时在同步器前面再加一级数字滤波连续 N 拍为低才认。现象五上电后系统完全不工作按复位键也没反应。原因复位同步器的复位源本身依赖时钟。比如同步器的arst_n接的是某个由 PLL 输出时钟产生的同步复位PLL 没锁定 → 没有时钟 → 同步器不工作 → 复位释放不出来 → PLL 也等不到复位释放死锁。 解决同步器第一级的复位必须来自不依赖时钟的源——外部引脚、上电复位电路或者 PLL 的locked反相后参与的逻辑。这条是下一章的主题。6. PLL 复位设计为什么复位必须走在时钟前面多时钟项目里几乎一定会用到片内 PLL 做分频倍频而 PLL 在上电后到锁定前有一段空窗期输出时钟可能根本没有、可能在扫频、可能频率抖动。如果这段时间用 PLL 输出时钟去驱动复位同步器同步器拿不到时钟复位就永远释放不出去如果它碰巧有时钟释放时刻又是随机的下游各模块退出复位的顺序完全不可控。原文给出的思路很直接用 FPGA 的外部输入时钟先把输入复位做异步复位同步释放得到的复位送进 PLL 的异步复位端同时把同一个外部时钟送进 PLL 的参考输入。这样 PLL 自身的复位由外部时钟域保证不依赖它自己的输出等 PLL 锁定之后再用 PLL 输出时钟对locked做一次同步产生各时钟域真正的复位。核心原则可以概括成一句复位树的每一级都必须由比它更“早存在”的时钟来同步。6.1 复位释放顺序与多时钟域一旦系统里有多个时钟域复位就不再是一根线的事而是一个顺序问题。合理的做法是每个时钟域各配一个复位同步器同步器的异步复位源统一来自那个由外部时钟域产生的、已经同步释放过的复位。这样所有域的复位“有效”是同时的都走异步路径释放则各自对齐到自己的时钟沿——同时进入复位、分别退出复位避免了跨域握手期间的状态不一致。代价是复位树面积和布线压力。每个同步器要占两个触发器一个系统里几十个时钟域就是几十份复位网络扇出极大工具会大量复制寄存器。要不要为了省这些资源把某些小模块的复位合并到主复位上取决于那个模块是否存在跨域交互——存在就必须独立同步不存在才可以合并。这一点没有普适答案得看具体划分。6.2 一个我踩过的取舍早年做过一个多时钟采集系统为了省资源把几个低速模块的复位直接挂在主复位上没做独立同步理由是“它们跟主时钟域没有数据交互”。后来发现其中一路会在主复位释放后、自己时钟域还没稳定时短暂输出无效数据正好被另一路采样到故障表现为偶发的首帧错误。补上独立同步器只多了四个触发器但那个 bug 我查了三天。从那以后我每次开新项目画复位树那一步都强制走一遍列出所有时钟域逐个确认复位源、同步器位置、释放顺序画成一张表贴在文档里再动手写代码。多花的这半小时比后面查一个偶发故障划算太多。希望帮到你。本文还有配套的精品资源点击获取