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 综合的标准流程

我总结了一套流程,用了好几年,基本没出过大问题:

  1. 读入设计:analyze + elaborate,把 RTL 吃进去
  2. 设置约束:时钟、输入输出延迟、驱动强度、负载电容
  3. 选择策略:面积优先还是速度优先?
  4. 运行综合:compile 或 compile_ultra
  5. 分析结果:看时序、面积、功耗报告
  6. 迭代优化:不满意就调约束或改 RTL

我的习惯:第一次综合用 compile,快速看结果。确认方向对了再用 compile_ultra 做精细优化。别一上来就跑 ultra,浪费时间。

3.4 综合流程的 SVG 图

逻辑综合标准流程 RTL 代码 工艺库 (.lib) 约束 (.sdc) 步骤1:读入设计 (analyze + elaborate) 步骤2:设置约束 (时钟/IO/驱动) 步骤3:选择综合策略 步骤4:运行综合 (compile) 输出:门级网表 + 报告 不满意就迭代,别怕重跑

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 综合后的检查清单

综合跑完了,别急着往后走。我每次都会过一遍这个清单:

  1. 网表完整性:所有模块都在吗?有没有 missing module?
  2. 时序收敛:setup/hold 违例在可接受范围内吗?
  3. 面积合理性:和预估比,偏差大不大?
  4. 功耗预估:动态功耗和静态功耗的比例正常吗?
  5. DRC 检查:有没有 max_transition、max_capacitance 违例?

我的经验:综合后的 DRC 违例,很多是约束设得太松或者太紧造成的。先检查约束,别急着改 RTL。

3.8 常见问题与避坑

这些年我遇到过的综合问题,挑几个典型的说说:

  • 综合出来的面积比预期大很多:检查是不是有未使用的逻辑,或者约束太紧导致工具过度优化
  • 时序不收敛:先看时钟约束对不对,再看关键路径是不是在预料的位置
  • 综合报错说找不到模块:检查文件路径和模块名大小写,Linux 下大小写敏感
  • 综合结果和仿真不一致:大概率是 RTL 里有不可综合的语法,比如 initial、delay 控制

嗯,逻辑综合这块内容不少,但核心就是那几步。多跑几次,多看看报告,慢慢就有感觉了。综合不是一次就能搞定的,迭代才是常态。