复位同步器:异步断言、同步释放
一句话回答
复位同步器实现「异步断言、同步释放」:复位按下时用异步复位立刻生效(不用等时钟);复位撤除时让它经过本时钟域的两级触发器,在时钟沿之后同步地撤掉,确保所有触发器在同一拍一起离开复位、且释放边沿不会落在时钟沿附近造成亚稳态和「有的出来了有的没出来」的撕裂。
一、问题根源
- 异步复位 assert:立即、确定,符合上电需求;
- 异步复位 deassert:若在时钟沿附近释放,会违反触发器的 recovery/removal 时间 → 亚稳态;不同触发器复位树延迟不同,会有几个先释放、几个后释放,启动状态不一致。
二、标准电路
verilog
module reset_sync (
input clk,
input async_rst_n, // 外部复位(低有效),可异步到来
output sync_rst_n
);
logic r1, r2;
always_ff @(posedge clk or negedge async_rst_n) begin
if (!async_rst_n) begin r1 <= 1'b0; r2 <= 1'b0; end // 立即断言
else begin r1 <= 1'b1; r2 <= r1; end // 同步释放
end
assign sync_rst_n = r2;
endmodule- 复位按下:
r1/r2立刻清零,全芯片马上进复位; - 复位松开:要等两个时钟沿,
r2才拉高,释放边沿与时钟对齐; - 下游触发器用
sync_rst_n作异步复位。
三、使用要点
- 每个时钟域一个复位同步器:不能拿 A 域同步后的复位去复位 B 域;
- 复位树要保证 assert 到达所有触发器;STA 检查 recovery/removal;
- 同步器的释放路径要设约束(类似异步 CDC),工具按同步器处理;
- 也可配合专用复位同步单元(库 cell)。
常见坑
- 只异步、释放不同步:启动时偶发系统起不来,极难复现。
- 一个同步器带多个时钟域:跨域复位同样有亚稳态,每域独立。
- 同步器本身时钟还没起:上电时钟稳定逻辑/POR 要配合,先有时钟再同步释放。
- 复位释放路径被优化/时序不检查:要保留两级并约束。
- 混用不同复位极性/来源:多个复位源要先合并再同步。
- 复位宽度不足:确保复位低电平持续足够长时间,所有触发器可靠复位。
总结
复位同步器用「异步置 0、同步撤 1」的两级电路实现异步断言、同步释放:按下立即生效,松开对齐时钟沿后两级延迟再撤除,避免 recovery/removal 违例和复位释放撕裂;每个时钟域要独立配一个同步器,并检查复位树、宽度和 recovery/removal 时序。