逻辑综合基础:从RTL到网表的第一次握手
逻辑综合,说白了就是把我们写的RTL代码,翻译成芯片真正能用的“零件清单”——门级网表。我刚开始接触这步时,觉得不就是个翻译工具嘛。后来被一个时序违例折腾了三天,才明白综合远不止“翻译”这么简单。
综合的概念与目的
综合是什么?我习惯这么理解:
- 输入:RTL代码(你写的硬件描述)
- 输出:门级网表(标准单元组成的连接清单)
- 约束:时序、面积、功耗等目标
- 库:标准单元库(工艺厂给的“积木”)
综合工具(比如Design Compiler)要做的,就是在满足你所有约束的前提下,用库里的单元拼出一个最优电路。嗯,这里要注意——它不是你代码的“逐字翻译”,而是会做大量优化。
核心目的三句话:
- 把行为级描述转换成结构级实现
- 在时序、面积、功耗之间找到平衡点
- 为后续的布局布线提供可实现的网表
我在项目中遇到过最典型的例子:同样的RTL,换了个工艺库,综合出来的面积差了30%。你想想看,库的选择有多重要。
RTL到网表的转换过程
这个转换不是一步到位的。我习惯把它拆成三个阶段:
| 阶段 | 做什么 | 输出 |
|---|---|---|
| 翻译 | 把RTL解析成内部通用逻辑(GTECH) | 与工艺无关的逻辑网表 |
| 优化 | 逻辑化简、资源共享、重定时等 | 优化后的逻辑网表 |
| 映射 | 把逻辑网表匹配到标准单元库 | 工艺相关的门级网表 |
举个例子,你写了个 assign y = a & b | a & c;,综合工具会先把它翻译成内部表示,然后优化成 y = a & (b | c),最后再映射成具体的与非门、或门。我曾经见过一个新人,发现综合后的面积比预期大很多,查了半天——原来是代码里写了很多冗余逻辑,工具优化时没完全吃掉。
我的习惯:在综合前先用lint工具扫一遍RTL。很多综合阶段才会暴露的问题,lint阶段就能发现。省时间,真的省时间。
标准单元库的理解
标准单元库,就是工艺厂给你的一盒“乐高积木”。每个单元都有固定的功能、尺寸、时序参数。我个人习惯把库里的信息分成三类:
- 逻辑功能:与门、或门、触发器、锁存器……
- 时序参数:延迟、建立时间、保持时间、转换时间
- 物理信息:面积、功耗、驱动能力、引脚位置
这里有个坑,我踩过——不同驱动强度的单元,延迟差别很大。比如一个2倍驱动的与非门,和8倍驱动的,面积差了4倍,但延迟可能只改善20%。你想想看,是不是所有地方都用大驱动单元就划算?不是的。
我曾经犯过的错:在一个时钟网络上全部用了最大驱动单元,结果功耗爆了,而且因为驱动过大,信号反射严重,波形反而变差了。后来改成树形结构,逐级增大驱动,才解决问题。
标准单元库通常还会提供多种 VT(阈值电压) 选项:
| 类型 | 速度 | 漏电 | 典型用途 |
|---|---|---|---|
| 高阈值(HVT) | 慢 | 低 | 非关键路径 |
| 标准阈值(SVT) | 中 | 中 | 一般路径 |
| 低阈值(LVT) | 快 | 高 | 关键路径 |
综合时,工具会根据时序压力自动选择不同VT的单元。但如果你不告诉它哪些路径是关键的,它可能会在非关键路径上也用LVT——功耗就上去了。
综合约束的初步认识
约束,就是告诉综合工具:“你要做到什么程度”。没有约束的综合,就像没有目的地的导航——工具会随便选一条路。
最基本的约束包括:
- 时钟约束:周期、占空比、抖动、延迟
- 输入输出延迟:数据从外部到内部/从内部到外部的可用时间
- 环境约束:温度、电压、工艺角
- 设计规则约束:最大扇出、最大转换时间、最大电容
举个实际例子:
# 时钟约束
create_clock -name clk -period 10 [get_ports clk]
set_clock_uncertainty -setup 0.2 [get_clocks clk]
# 输入输出延迟
set_input_delay -max 2.0 -clock clk [get_ports data_in]
set_output_delay -max 1.5 -clock clk [get_ports data_out]
# 设计规则
set_max_fanout 20 [current_design]
set_max_transition 0.5 [current_design]
我刚开始做综合时,经常把约束设得太松。结果呢?综合报告一片绿,到了布局布线阶段,时序全红了。后来学乖了——约束要设得“紧一点”,给后端留余量。
一个实用的经验值:时钟周期约束可以比目标频率紧5%-10%。比如目标500MHz(周期2ns),我习惯设成1.9ns。这样综合出来的网表,在后端流程中更容易收敛。
本章知识体系
下面这张图,是我自己总结的综合流程框架,你可以对照着理解:
这张图把综合的输入、过程、输出和核心要素串起来了。你对照着看,应该能对综合有个整体认识。
一个小建议:刚开始学综合,别急着调复杂策略。先把约束写对,把库选对,把代码写干净。这三件事做好了,综合结果不会差到哪里去。