同步复位和异步复位有什么区别?
一句话回答
同步复位的复位信号只在时钟有效沿被采样、和时钟「同步」生效,抗毛刺但必须有时钟在跑、还要占用触发器输入端的组合逻辑;异步复位一按下去立刻生效、不需要时钟、省资源,但「解除复位」的时刻若恰好落在时钟沿附近,会造成有的触发器已退出复位、有的还没有(亚稳态/恢复时间违例),整芯片启动不一致。所以工程上最常用「异步断言、同步释放」(异步复位同步解除)的复位同步器。
核心对照
| 维度 | 同步复位 | 异步复位 |
|---|---|---|
| 生效时机 | 时钟有效沿才生效 | 立刻生效,不依赖时钟 |
| Verilog | always@(posedge clk) 里判断 rst | always@(posedge clk or negedge rst_n) |
| 抗毛刺 | 好(毛刺不在沿上被忽略) | 差(窄毛刺也可能触发复位) |
| 需要时钟 | 是(时钟没起振无法复位) | 否,上电即可复位 |
| 资源/时序 | 占 D 端组合逻辑,复位路径要过 setup | 用专用复位引脚,省逻辑 |
| 主要风险 | 复位脉冲过短可能漏采 | 释放时刻靠时钟沿 → 亚稳态/恢复违例 |
为什么「异步复位、同步释放」
异步复位的优点(立即、无需时钟、省资源)保留下来,同时用一小段复位同步逻辑消除「释放不同步」的风险:
verilog
// 复位同步器:外部异步复位 assert 立即传播;deassert 经两级同步后再放行
reg r1, r2;
always @(posedge clk or negedge rst_async_n) begin
if (!rst_async_n) {r2, r1} <= 2'b00; // 异步断言:立刻拉低
else {r2, r1} <= {r1, 1'b1}; // 同步释放:随时钟逐拍恢复
end
wire rst_sync_n = r2; // 给本时钟域的异步复位- **assert(按下)**走异步,保证任何时刻(含时钟未就绪)都能可靠复位。
- **deassert(释放)**经过本时钟域两级触发器同步,使复位撤销沿与时钟对齐,所有 FF 在同一拍干净退出,避免 recovery/removal 违例和亚稳态,原理同 CDC 两级同步器。
复位域交叉(RDC)
不同模块用不同复位时,跨越复位域的信号同样可能产生亚稳态/X 传播,需要 RDC 检查与同步,见 RDC 复位域交叉。全芯片还涉及上电复位 POR、复位顺序、异步断言同步释放的统一策略,见 系统复位/POR。
常见坑
- 异步复位直接接所有 FF 又不做同步释放:释放碰时钟沿,启动状态随机、极难复现。
- 同步复位但时钟没起来/被门控:根本复不了位(门控时钟测试时也要处理,见 门控时钟)。
- 复位信号有毛刺/抖动(按键):异步侧会误触发,需消抖/滤波。
- 跨复位域数据不做 RDC 处理:X 态传播打挂下游。
- 复位极性/有效电平在模块间不一致,或复位树扇出过大没做缓冲。
总结
同步复位靠时钟沿生效、抗毛刺但依赖时钟且占组合资源;异步复位立即生效、省资源却在释放时可能撞上时钟沿造成亚稳态和恢复违例;最佳实践是「异步断言 + 同步释放」的复位同步器,既保证随时可靠复位又让各触发器同一拍干净退出,并对多复位域做 RDC 检查。