第三章 逻辑综合入门
逻辑综合,说白了就是把你的RTL代码翻译成门级网表。我刚开始接触这步时,觉得它就是个黑盒子——代码丢进去,网表吐出来。后来踩过几次坑才明白,这步要是没做好,后面时序收敛能让你怀疑人生。
3.1 什么是逻辑综合
逻辑综合,就是把硬件描述语言(Verilog/VHDL)写的RTL代码,转换成由标准单元库里的门级电路组成的网表。这个过程由EDA工具自动完成,比如Synopsys的Design Compiler、Cadence的Genus。
我个人习惯把综合分成三步:
- 翻译:工具读入RTL代码,解析成内部的数据结构
- 优化:根据你给的约束,对电路进行面积、时序、功耗的权衡
- 映射:把优化后的电路,映射到目标工艺库的标准单元上
你想想看,这就像写作文——翻译是把思路变成草稿,优化是修改措辞,映射是誊写到正式稿纸上。每一步都影响最终质量。
核心要点:综合不是简单的翻译,而是带约束的优化过程。没有约束的综合,就像没有导航的开车——能跑,但不知道跑哪去。
3.2 综合的输入与输出
综合的输入文件,其实比你想象的多。我见过不少新手只给RTL代码就跑综合,结果工具报一堆错。来看看完整的输入清单:
| 输入文件 | 说明 | 是否必需 |
|---|---|---|
| RTL代码 | Verilog/VHDL/SystemVerilog | 必需 |
| 工艺库 | 标准单元库(.lib/.db) | 必需 |
| 综合约束 | SDC文件(时序、面积、功耗) | 强烈建议 |
| 线载模型 | 预估互连线延迟(.tcl) | 可选 |
| 操作条件 | PVT条件(工艺、电压、温度) | 必需 |
输出文件呢,主要有这些:
- 门级网表(.v/.vg):综合后的电路连接关系
- 综合报告(.rpt):时序、面积、功耗的详细数据
- SDC约束文件:综合后的约束,给后端用
- DFT相关文件:如果做了可测性设计
小技巧:我习惯在综合前先检查工艺库是否完整。曾经有一次,工艺库少了一个关键单元的.lib文件,综合结果面积大了30%。嗯,从那以后我每次都会跑一下库检查脚本。
3.3 RTL到网表的转换
这个转换过程,工具内部是怎么做的?我简单说说,不涉及太深的理论。
工具先把RTL代码解析成抽象语法树(AST),然后识别出里面的寄存器、组合逻辑、状态机等结构。接着,它会根据你给的约束,决定每个逻辑块用什么电路实现。
举个例子,你写了个加法器:
assign sum = a + b;
工具会怎么处理?它会查工艺库里有哪些加法器单元。如果时序要求高,它可能选超前进位加法器;如果面积优先,可能选行波进位加法器。这就是优化和映射的过程。
我记得有个项目,RTL里写了个很大的case语句,工具综合出来面积爆炸。后来发现是case语句没写default分支,工具默认生成了优先级编码器。改成full case后,面积降了40%。
避坑指南:我曾经因为RTL里用了太多for循环,综合出来一个巨大的组合逻辑链。工具优化了半天,时序还是过不了。后来改成流水线结构,问题才解决。记住:RTL风格直接影响综合质量。
3.4 综合约束基础
综合约束,说白了就是告诉工具:你要达到什么目标。没有约束的综合,工具只会按默认策略做,结果往往不是你想要的。
最常用的约束是时序约束,用SDC格式写。我列几个必用的:
# 创建时钟
create_clock -name clk -period 10 [get_ports clk]
# 设置输入延迟
set_input_delay -max 5 -clock clk [get_ports data_in]
# 设置输出延迟
set_output_delay -max 5 -clock clk [get_ports data_out]
# 设置伪路径
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]
约束里有个容易搞混的概念:建立时间和保持时间。我简单解释下:
- 建立时间:数据在时钟沿之前必须稳定的时间
- 保持时间:数据在时钟沿之后必须稳定的时间
综合工具会检查每个寄存器的建立时间和保持时间是否满足。如果建立时间违例,可以降低频率或优化路径;如果保持时间违例,通常要插入缓冲器。
经验之谈:我建议新手先只设时钟约束跑一次综合,看看默认结果。然后再加输入输出延迟,逐步收紧约束。一步到位设太紧,工具可能优化到死循环。
3.5 综合策略
综合策略,就是你怎么指挥工具干活。不同的策略,结果差异很大。我常用的策略有这几种:
| 策略 | 适用场景 | 特点 |
|---|---|---|
| 面积优先 | 成本敏感、时序宽松 | 面积小,但时序可能差 |
| 时序优先 | 高性能设计 | 时序好,但面积大 |
| 功耗优先 | 低功耗设计 | 功耗低,但性能折中 |
| 平衡策略 | 大多数设计 | 三者兼顾 |
我个人习惯先用平衡策略跑一版,看看时序和面积的基线。然后根据结果,决定往哪个方向调。比如时序紧张,就切到时序优先,同时放宽面积约束。
还有个策略叫自顶向下和自底向上:
- 自顶向下:整个设计一起综合,工具全局优化。适合小设计。
- 自底向上:先综合每个模块,再拼起来。适合大设计,可以并行跑。
我记得有个芯片,规模太大,自顶向下综合跑了三天没跑完。后来改成自底向上,每个模块单独综合,一天就搞定了。但要注意,模块间的接口约束要设准,不然拼起来时序乱套。
实用建议:综合策略不是一成不变的。我一般会跑3-5版不同策略的综合,对比报告后选最优的。工具只是工具,决策还得靠人。
知识体系总览
下面这张图,把本章的核心逻辑串起来了。你可以对照着看,理解综合的完整流程。
这张图把综合的输入、过程、输出、约束和策略串在了一起。你仔细看看,会发现核心就一句话:输入决定起点,约束决定方向,策略决定路径。
好了,逻辑综合入门就讲这么多。记住,综合不是一锤子买卖,多跑几版对比,才能找到最优解。我当年也是从一次次失败中总结出来的经验,希望你少走弯路。