4、逻辑综合优化:面积、时序与功耗的权衡,Yosys中的优化命令

好,咱们进入逻辑综合最核心的部分——优化。

说白了,综合就是把RTL代码变成门级网表。但光变出来不行,你还得让它满足面积小、跑得快、功耗低这三个要求。可惜,这三者往往是互相打架的。你想想看,想让电路跑得快,就得用大驱动单元,面积就大了,功耗也跟着涨。想省面积,用最小尺寸的单元,时序又可能崩了。

这就是我们常说的PPA(Performance, Power, Area)三角权衡。我在项目中遇到过好几次,老板说“面积再压一压”,结果时序直接红了,最后又得往回退。所以,做优化之前,心里得有个优先级。

4.1 优化的三个维度:面积、时序、功耗

咱们先简单捋一下这三个维度在Yosys里是怎么体现的。

  • 面积优化:说白了就是减少使用的逻辑门数量。Yosys会尝试共享公共子表达式,合并冗余逻辑。
  • 时序优化:目标是减少关键路径的延迟。Yosys会通过逻辑重组、单元重映射来缩短路径。
  • 功耗优化:这个在Yosys里相对弱一些,主要是通过门控时钟(如果RTL写了)和减少不必要的翻转来实现。

我个人习惯,在综合初期先跑一遍面积优化,看看网表有多大。然后根据时序约束,再跑一遍时序优化。最后回头看看功耗,如果功耗超标,再针对性调整。

核心原则:没有完美的优化,只有满足约束的优化。你的目标是让设计“刚好”满足时序,同时面积和功耗尽可能小。

4.2 Yosys中的优化命令详解

Yosys提供了很多优化命令。我挑几个最常用的,也是我平时用得最多的,给你讲讲。

4.2.1 opt:通用优化命令

opt 是Yosys的瑞士军刀。它会自动执行一系列标准优化步骤。我建议你每次做完一个大的变换后,都跑一遍 opt

# 最简单的用法
opt

# 带选项的用法,比如只做常数传播
opt -full

这个命令会做常数传播、简化表达式、删除未使用的信号等等。嗯,这里要注意,opt -full 会做更激进的优化,有时候会把一些你故意保留的层次结构给优化掉。如果你需要保留某些层次,慎用。

4.2.2 share:资源共享

这个命令专门用来减少面积。它会查找设计中可以共享的运算单元,比如多个加法器如果输入有重叠,它可以合并成一个。

# 共享算术单元
share

我曾经在一个图像处理模块里,发现两个乘法器其实可以共享,因为它们的输入在大部分时间是一样的。用 share 之后,面积直接降了15%。

4.2.3 abc:调用ABC工具进行逻辑综合

这是Yosys里最强大的优化命令。ABC是一个外部逻辑综合工具,Yosys可以调用它来做深层次的逻辑优化,包括技术映射和时序驱动优化。

# 基本用法,使用标准单元库进行映射
abc -liberty my_library.lib

# 时序驱动优化,需要提供SDC约束
abc -liberty my_library.lib -constr my_constraints.sdc

我个人习惯,在综合流程的最后阶段,一定会跑一遍 abc 来做最终的时序优化。它会根据你的时序约束,重新选择标准单元,比如把慢的单元换成快的,或者调整逻辑结构。

小技巧:如果你发现时序不满足,可以试试 abc -dff 选项。这个选项会让ABC尝试优化寄存器之间的逻辑,有时候效果出奇的好。

4.2.4 splitnetsopt_clean:清理网表

这两个命令虽然不起眼,但很重要。splitnets 会把多bit的线网拆成单bit的,方便后续优化。opt_clean 会删除所有没有输出的模块和信号。

# 拆分线网
splitnets

# 清理未使用的信号和模块
opt_clean

我建议你在每次优化之后,都跑一遍 opt_clean。不然网表里会残留很多“垃圾”,影响后续的分析。

4.3 优化策略:先面积,后时序,再功耗

在实际项目中,我一般会按这个顺序来:

  1. 第一步:面积优化。先用 optshare 把面积压到最小。这时候时序可能很差,没关系。
  2. 第二步:时序优化。加载时序约束,用 abc 做时序驱动优化。如果时序不满足,我会回头看看RTL代码,是不是哪里写得太复杂了。
  3. 第三步:功耗优化。Yosys本身对功耗优化支持有限,但你可以通过 setundef 命令把未定义的信号设为0,减少不必要的翻转。另外,检查一下门控时钟是否被正确综合了。

避坑指南:我曾经在一个项目中,为了追求极致的面积,把 opt -fullshare 都用上了。结果综合出来的网表时序完全乱套,关键路径比预期长了30%。后来我才发现,过度共享导致逻辑深度增加了。所以,优化要适度,不要为了省一点面积而牺牲时序。

4.4 一个完整的优化脚本示例

最后,给你一个我常用的优化脚本片段,你可以直接拿去用。

# 读取设计后,先做基本优化
hierarchy -check
proc
opt
fsm
opt
share
opt

# 拆分线网并清理
splitnets
opt_clean

# 技术映射和时序优化
abc -liberty my_library.lib -constr my_constraints.sdc

# 再次清理
opt_clean

# 检查统计信息
stat -liberty my_library.lib

这个脚本覆盖了从基本优化到时序优化的全过程。你只需要替换 my_library.libmy_constraints.sdc 为你自己的文件就行。

好了,关于逻辑综合优化,咱们就聊到这儿。记住,优化不是一蹴而就的,需要反复迭代。多跑几次,多看看报告,慢慢你就有感觉了。