3. 逻辑综合基础:RTL到网表的转换
逻辑综合,说白了就是把我们写的 RTL 代码,翻译成芯片能用的门级网表。很多刚入行的朋友觉得这步就是点一下按钮的事。嗯,我当年也这么想,直到有一次综合出来的面积比预期大了 30%,才老老实实回去研究综合的每个细节。
3.1 综合到底在做什么?
综合不是简单的翻译。它要干三件事:
- 转换:把 Verilog/VHDL 转成布尔表达式
- 优化:根据你的约束,选择最优的门电路实现
- 映射:把优化后的电路映射到工艺库里的标准单元
我习惯把综合比作翻译+装修。RTL 是设计图纸,综合工具是施工队,工艺库就是建材清单。图纸画得再好,施工队看不懂也不行;建材选得再贵,不符合图纸要求也是白搭。
核心要点:综合的输入是 RTL + 约束 + 工艺库,输出是门级网表 + 时序报告 + 面积报告。
3.2 综合的输入输出
先看看综合到底需要什么,又吐出什么。
| 输入 | 说明 | 我踩过的坑 |
|---|---|---|
| RTL 代码 | Verilog/VHDL/SystemVerilog | 记得检查语法,有一次我漏了个 always 块,综合出来少了一半逻辑 |
| 工艺库 | .lib / .db 文件 | 不同工艺节点库不能混用,28nm 的库用在 40nm 上,时序全乱 |
| 约束文件 | .sdc / .xdc | 时钟定义错了,后面 STA 全是废的 |
| 综合脚本 | .tcl / .dcsh | 脚本里路径写错,折腾一整天 |
| 输出 | 说明 | 怎么看 |
|---|---|---|
| 门级网表 | .v / .vg | 检查顶层模块名对不对 |
| 时序报告 | .rpt | 重点看 setup/hold 违例 |
| 面积报告 | .rpt | 对比预估面积,偏差超过 20% 要查原因 |
| 功耗报告 | .rpt | 动态功耗和静态功耗分开看 |
3.3 综合的标准流程
我总结了一套流程,用了好几年,基本没出过大问题:
- 读入设计:analyze + elaborate,把 RTL 吃进去
- 设置约束:时钟、输入输出延迟、驱动强度、负载电容
- 选择策略:面积优先还是速度优先?
- 运行综合:compile 或 compile_ultra
- 分析结果:看时序、面积、功耗报告
- 迭代优化:不满意就调约束或改 RTL
我的习惯:第一次综合用 compile,快速看结果。确认方向对了再用 compile_ultra 做精细优化。别一上来就跑 ultra,浪费时间。
3.4 综合流程的 SVG 图
3.5 综合脚本示例
给你看一段我常用的综合脚本框架:
# 读入设计
analyze -format verilog {top.v datapath.v controller.v}
elaborate top
# 设置时钟
create_clock -name clk -period 10 [get_ports clk]
set_clock_uncertainty 0.5 [get_clocks clk]
# 设置输入输出延迟
set_input_delay 2 -clock clk [all_inputs]
set_output_delay 2 -clock clk [all_outputs]
# 运行综合
compile -map_effort high -area_effort medium
# 输出结果
write -format verilog -hierarchy -output mapped.v
report_timing > timing.rpt
report_area > area.rpt
注意:脚本里的路径一定要用路径或者相对路径写清楚。我曾经用相对路径,换了个目录跑综合,结果读不到库文件,折腾了两小时才发现是路径问题。
3.6 综合策略怎么选?
综合策略不是一成不变的。我一般这么选:
- 面积优先:芯片面积紧张,或者成本敏感的项目
- 速度优先:高频设计,比如 CPU、GPU
- 功耗优先:移动设备、IoT 芯片
- 平衡策略:大部分项目选这个,省心
你想想看,如果做的是 28nm 以下的先进工艺,面积和功耗的 trade-off 就更复杂了。我建议刚开始做综合的朋友,先用平衡策略跑一遍,看看结果再决定要不要调整。
3.7 综合后的检查清单
综合跑完了,别急着往后走。我每次都会过一遍这个清单:
- 网表完整性:所有模块都在吗?有没有 missing module?
- 时序收敛:setup/hold 违例在可接受范围内吗?
- 面积合理性:和预估比,偏差大不大?
- 功耗预估:动态功耗和静态功耗的比例正常吗?
- DRC 检查:有没有 max_transition、max_capacitance 违例?
我的经验:综合后的 DRC 违例,很多是约束设得太松或者太紧造成的。先检查约束,别急着改 RTL。
3.8 常见问题与避坑
这些年我遇到过的综合问题,挑几个典型的说说:
- 综合出来的面积比预期大很多:检查是不是有未使用的逻辑,或者约束太紧导致工具过度优化
- 时序不收敛:先看时钟约束对不对,再看关键路径是不是在预料的位置
- 综合报错说找不到模块:检查文件路径和模块名大小写,Linux 下大小写敏感
- 综合结果和仿真不一致:大概率是 RTL 里有不可综合的语法,比如 initial、delay 控制
嗯,逻辑综合这块内容不少,但核心就是那几步。多跑几次,多看看报告,慢慢就有感觉了。综合不是一次就能搞定的,迭代才是常态。