1. 时序仿真概述
讲时序仿真之前,我们先聊聊“仿真”到底在干什么。你写了一大堆 RTL 代码,功能正确不代表它能在真实芯片里跑得稳。我刚开始做设计时,觉得功能仿真过了就万事大吉,结果有一次投片前做后仿真,发现一根关键路径差了 0.2ns。嗯,从那以后我再也不敢小看时序仿真了。
1.1 什么是时序仿真
时序仿真,说白了就是带着“真实延迟”去跑仿真。功能仿真只关心逻辑对不对,门级信号是什么时候跳变的它不管。但时序仿真会把工艺库里的单元延迟、互连线延迟全部塞进来,然后告诉你:这个信号在时钟沿之前到底稳定了没有。
我个人习惯把时序仿真叫做“带延迟信息的门级仿真”。它通常是在综合后或布局布线后进行的。你用反标的 SDF(标准延迟格式)文件,把它和网表一起喂给仿真器,仿真器就会按照真实的延迟去计算每个信号的变化时刻。
关键点:时序仿真的目的不是测功能,而是测“时序裕量”。看 setup 和 hold 有没有违反,看时钟能否正确采样数据。
1.2 时序仿真与功能仿真的区别
很多新人容易混淆这两个概念。我遇到过一个同事,功能仿真跑了几万个向量全绿,结果后仿真直接崩了。为什么?因为功能仿真里信号是理想跳变,没有延迟竞争。而时序仿真会把门级路径上的延迟暴露出来,那些隐藏的冒险、毛刺、亚稳态全都会浮出水面。
下面这张表对比了三者的核心差异:
| 对比项 | 功能仿真 | 时序仿真 |
|---|---|---|
| 延迟模型 | 零延迟 / 单位延迟 | 真实工艺延迟(SDF) |
| 仿真对象 | RTL 代码 / 行为级模型 | 门级网表 + 反标延迟 |
| 检查内容 | 逻辑功能正确性 | 时序约束满足(setup/hold) |
| 速度 | 快(百万周期/秒) | 慢(几千周期/秒) |
| 典型用途 | 前期验证算法、状态机 | 后仿流程、Signoff 检查 |
小提示:功能仿真过了只是第一步。千万别把功能仿真当成万事大吉——我见过好几个案例,功能仿真的覆盖率都到 95% 了,后仿照样跑出 setup 违例。因为功能仿真根本不看路径延迟。
1.3 时序分析在数字 IC 设计流程中的位置
你知道在整个数字 IC 设计流程里,时序相关的工作几乎贯穿始终。从综合开始,到静态时序分析(STA),再到后仿真,每一步都在跟时序博弈。
我一般把流程分成三个阶段:前端、中端和后端。时序仿真主要在“后端”的 Signoff 阶段出现,但它的输入依赖于前面的综合、布局布线、时钟树综合等步骤。
为了让你看得更清楚,我画了一张流程图:
从图里你能看到,时序仿真发生在布局布线之后、流片之前。它依赖寄生参数提取生成的 SDF 文件,把真实的 RC 延迟反标到门级网表上。这个阶段跑出的波形,可以反映芯片真正工作时的信号跳变。
1.4 时序仿真的核心目的
简单总结一下时序仿真到底在查什么:
- Setup 检查:数据必须在时钟沿之前稳定,延迟太大会导致建立时间违例。
- Hold 检查:数据必须在时钟沿之后保持稳定,延迟太小会导致保持时间违例。
- 时钟偏差:不同寄存器的时钟到达时间差是否在允许范围内。
- 异步处理:跨时钟域信号有没有同步处理,会不会产生亚稳态。
注意:时序仿真不能完全替代静态时序分析(STA)。STA 是遍历所有路径的数学分析,而时序仿真只跑你给的激励。我曾经遇到过一个项目,STA 报告干干净净,但后仿真却出现了时序违规。为什么?因为 STA 默认的是理想时钟,而仿真用的 SDF 包含了时钟树的真实偏差和一些寄生效应。所以两者不能互相替代,要相辅相成。
1.5 我个人的一点经验
写代码时,大部分人只关注功能。但到了后仿阶段,信号延迟导致的毛刺、竞争、亚稳态才是真正的噩梦。我建议你尽早养成习惯:在写 RTL 时,就要考虑时序裕量,给综合留够余量。否则后仿出了违例,回头改代码,代价可能是别的。
记得有一次,我做一个高速接口项目,前仿全绿,综合也通过了时序约束。但后仿时一条路径的 hold 老是违例,反复查,发现是时钟树综合时插入了太多 buffer,造成时钟偏斜。最后重做了时钟树,才解决问题。所以说,别等到后仿才去关注时序,从综合开始就要反复迭代。
实用建议:每完成一次布局布线,就立刻导出 SDF 跑一个简单的后仿测试。哪怕只跑几个周期,也能快速暴露那些“让工程师头疼”的时序问题。别等到最后集成时才跑,那时候改东西成本太高了。
这一章我们先把时序仿真的概念和位置理清楚了。接下来你会开始接触更具体的操作方法——比如怎么生成 SDF、怎么反标、怎么看波形里的时序违规。别急,一步一个脚印来。