时钟域与复位设计:时钟域划分策略、异步复位同步释放、时钟门控对时序的影响
大家好,我是老李。做AXI互连设计这么多年,我最大的体会就是——时钟和复位要是没整明白,后面时序收敛基本就是碰运气。今天咱们就聊聊这个基础但极其关键的话题。
一、时钟域划分策略
时钟域划分,说白了就是把芯片里不同频率、不同相位的时钟区域给切分开。为什么要切?因为跨时钟域的数据传递,搞不好就出亚稳态,芯片直接罢工。
我个人习惯,在项目一开始就用一张时钟域地图把整个芯片的时钟关系画清楚。比如AXI互连中,通常会有:
- 主时钟域:比如200MHz的系统时钟
- 从时钟域:可能是100MHz或150MHz的外设时钟
- 异步时钟域:比如来自外部晶振的独立时钟
我遇到过最头疼的情况,是一个项目里混了5个时钟域,结果跨时钟域路径没处理好,仿真没问题,一上FPGA就随机出错。后来花了整整两周才定位到问题。
核心原则:同频同相的时钟尽量合并,不同频不同相的时钟必须用同步器隔离。
这里我画了一张时钟域划分的示意图,帮你快速理解:
你想想看,如果两个时钟域之间没有同步器,数据直接跨过去,那亚稳态的概率有多大?说白了就是赌运气。我从来不敢这么干。
二、异步复位同步释放
复位设计,很多新手觉得简单——不就是给个复位信号嘛。其实这里坑很多。
异步复位的好处是响应快,复位信号一来,寄存器立刻清零。但问题也在这里:如果复位信号在时钟沿附近撤销,寄存器可能进入亚稳态。
同步释放就是解决这个问题的。它的思路是:复位生效时异步立即复位,但复位撤销时,让它在时钟域里同步一下再释放。
我的经验:在AXI互连中,每个时钟域都应该有自己的复位同步器。不要图省事把全局复位直接连到所有寄存器上。
来看一个典型的异步复位同步释放电路:
// 异步复位同步释放电路
module rst_sync (
input wire clk,
input wire rst_n, // 异步复位输入
output wire rst_sync_n // 同步后的复位输出
);
reg rst_meta, rst_sync;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rst_meta <= 1'b0;
rst_sync <= 1'b0;
end else begin
rst_meta <= 1'b1;
rst_sync <= rst_meta;
end
end
assign rst_sync_n = rst_sync;
endmodule
这段代码里,第一级寄存器rst_meta可能会产生亚稳态,但经过一个时钟周期后,第二级寄存器rst_sync基本就稳定了。这就是「异步复位,同步释放」的精髓。
注意:两级同步器只能降低亚稳态概率,不能完全消除。对于超高速设计,我建议用三级同步器。
我曾经在一个项目中,因为复位同步器只做了一级,结果芯片在高温下偶尔复位失败。后来改成两级,问题就解决了。嗯,这里要注意,复位树的时序也要做STA,很多人会忽略这一点。
三、时钟门控对时序的影响
时钟门控,说白了就是通过一个使能信号来控制时钟是否传递给寄存器。这样做的好处是省电——寄存器不翻转就不耗动态功耗。
但时钟门控对时序的影响,很多人没想清楚。我总结了几点:
- 时钟歪斜增加:门控单元会引入额外的延迟,导致时钟到达时间不一致
- 建立时间变紧:门控信号本身需要满足建立时间要求,否则会产生毛刺
- 保持时间问题:门控时钟的占空比可能被改变,影响保持时间
来看一个常见的时钟门控单元:
// 时钟门控单元(带锁存器)
module clk_gate (
input wire clk,
input wire en,
output wire gclk
);
reg en_latch;
always @(*) begin
if (!clk) begin
en_latch = en; // 时钟低电平时锁存使能信号
end
end
assign gclk = clk & en_latch;
endmodule
为什么要在时钟低电平时锁存使能?因为这样可以避免在时钟高电平时改变使能信号,从而防止产生毛刺。这个技巧,我是在做第一个芯片项目时跟老工程师学的。
| 时钟门控方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 与门门控 | 结构简单 | 易产生毛刺 | 低频设计 |
| 锁存器+与门 | 无毛刺 | 面积稍大 | 主流设计 |
| ICG单元 | 集成度高,时序好 | 需要库支持 | 先进工艺 |
我个人建议,在AXI互连中,对数据路径尽量使用ICG单元,对控制路径可以用锁存器+与门的方式。为什么呢?因为数据路径对时序要求更严格,ICG单元经过工艺优化,时序更可控。
避坑指南:我曾经在AXI写数据通道上用了简单的与门门控,结果因为使能信号和时钟的相位关系没处理好,导致数据写错。后来全部换成ICG单元,问题才解决。
时钟门控还有一个容易被忽视的问题——门控时钟的STA分析。很多工具默认把门控时钟当成普通时钟处理,但实际上门控时钟的延迟和歪斜都更大。我建议在约束文件中明确指定门控时钟的属性,让工具做更精确的分析。
好了,关于时钟域和复位设计,今天就聊这么多。记住一句话:时钟域划分要清晰,复位同步要做足,时钟门控要谨慎。这三样做好了,时序收敛就成功了一半。
可可精品资料库