逻辑综合入门:RTL代码到门级网表的魔法
各位同学,欢迎来到第二章。上一章我们聊了芯片设计的整体流程,今天咱们来点实在的——逻辑综合。
说实话,我刚入行那会儿,觉得逻辑综合就是个黑盒子。RTL代码写进去,门级网表吐出来,中间发生了什么?完全不知道。后来踩了不少坑才明白,这玩意儿其实没那么玄乎。
逻辑综合,说白了就是把我们写的硬件描述语言(Verilog/VHDL)翻译成芯片厂能用的标准单元库里的门级电路。你想想看,我们写的是 if (a & b) c = 1;,但芯片里没有if语句,只有与门、或门、非门、触发器这些东西。综合工具就是做这个翻译工作的。
综合的三个阶段
综合工具(比如Synopsys的Design Compiler,简称DC)做这件事,一般分三步走:
- 转译(Translation):把RTL代码读进来,转成工具内部通用的布尔表达式。这一步很快,基本不花时间。
- 逻辑优化(Logic Optimization):对布尔表达式做化简。比如
a + a*b可以化简成a,这一步能省不少面积。 - 映射(Mapping):把优化后的逻辑表达式,映射到目标工艺库里的标准单元上。比如用两输入的与非门实现某个逻辑。
核心要点:综合不是简单的翻译,而是带着约束条件的优化过程。你给工具的约束越清晰,它产出的网表质量就越高。
我画了一张图,帮你理解这个过程:
DC的基本用法
Design Compiler是Synopsys家的旗舰产品,也是业界用得最多的综合工具。我个人的习惯是,先用脚本跑一遍,再打开GUI看看关键路径的时序报告。
一个典型的DC综合脚本长这样:
# 读入设计
read_verilog {top.v sub_module.v}
current_design top
# 链接工艺库
link
# 设置约束
create_clock -period 10 [get_ports clk]
set_input_delay 2 -clock clk [all_inputs]
set_output_delay 2 -clock clk [all_outputs]
# 综合
compile_ultra
# 输出结果
write -format verilog -output top_synth.v
write_sdc top_synth.sdc
report_timing > timing.rpt
report_area > area.rpt
这段脚本看着简单,但每个命令背后都有讲究。我挑几个重点说说:
create_clock -period 10:时钟周期设10ns,意味着目标频率是100MHz。设多少合适?得看你的设计复杂度和工艺节点。compile_ultra:这是DC的优化命令,比老版的compile效果更好。我在项目中遇到过,同样的RTL,用compile_ultra比compile时序能好10%~20%。write_sdc:输出时序约束文件,给后端布局布线用。这一步很多人会忘,但忘了的话后端同事会来找你喝茶的。
小技巧:跑综合之前,先跑一下check_design。这个命令能检查出RTL里的一些低级错误,比如悬空端口、多驱动之类的问题。我每次跑综合前必做这一步,能省不少debug时间。
时序约束初探
时序约束,说白了就是告诉综合工具:我的芯片要在多快的频率下工作,输入信号什么时候到,输出信号什么时候要准备好。
最基本的几个约束:
| 约束类型 | 命令示例 | 说明 |
|---|---|---|
| 时钟定义 | create_clock -period 10 [get_ports clk] |
定义时钟周期和端口 |
| 输入延迟 | set_input_delay 2 -clock clk [all_inputs] |
外部信号到达芯片输入端的延迟 |
| 输出延迟 | set_output_delay 2 -clock clk [all_outputs] |
芯片输出到外部器件需要的建立时间 |
| 伪路径 | set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b] |
告诉工具某些路径不需要分析时序 |
这里有个容易踩的坑——输入延迟和输出延迟。我曾经在一个项目里,把输入延迟设得太小,结果综合出来的网表面积特别大。后来才发现,输入延迟设小了,工具以为留给内部逻辑的时间很多,就拼命优化速度,结果面积爆了。
避坑指南:我曾经因为忘了设set_clock_uncertainty,导致芯片流片回来跑不到目标频率。时钟不确定性(clock uncertainty)是用来模拟时钟抖动和时钟偏斜的,一般设周期5%~10%。这个值设太小,时序可能hold不住;设太大,又过度约束导致面积变大。
综合后的检查
综合跑完,别急着下班。先看看报告:
- 时序报告:看最差路径的slack是多少。正数说明时序满足,负数说明有问题。
- 面积报告:看看用了多少门,有没有超出预算。
- 扇出报告:高扇出的信号(比如复位信号)可能导致时序问题。
嗯,这里要注意,综合后的时序报告只是预估,实际走线后的时序可能会有变化。所以一般会留10%~20%的余量。
好了,这一章的内容就到这儿。逻辑综合是连接前端设计和后端实现的桥梁,掌握了它,你就能理解为什么同样的RTL代码,换了个工艺库或者改了个约束,结果会差那么多。
下一章我们会聊到布局规划,看看门级网表是怎么变成芯片上的物理位置的。