第3章:逻辑综合与网表生成——从RTL到门级网表的流程

各位同学,今天我们来聊聊逻辑综合。说白了,就是把我们写的RTL代码,翻译成芯片厂能用的门级网表。这一步,是数字芯片设计里承上启下的关键环节。

我个人习惯把综合比作「翻译官」。你写的Verilog是中文,门级网表是英文,综合工具就是那个翻译。翻译得好不好,直接决定了芯片能不能跑起来、跑多快、功耗多少。

3.1 综合流程:三步走

综合不是一步到位的。我一般把它拆成三个阶段:

  1. 转译(Translation):把RTL代码读进去,转成工具内部的通用布尔表达式。这一步不优化,只是「读懂」你的设计。
  2. 逻辑优化(Logic Optimization):对布尔表达式做化简、资源共享、常数传播等。说白了,就是去掉冗余逻辑。
  3. 映射(Mapping):把优化后的逻辑,映射到目标工艺库里的标准单元(AND门、OR门、触发器、MUX等)。

嗯,这里要注意:映射这一步,直接决定了最终网表的面积和时序。我见过不少新手,RTL写得没问题,但映射出来的网表面积大得离谱——后来发现是综合约束没设好。

3.2 综合工具的两大阵营

目前主流工具就两个:Synopsys Design Compiler(DC)和开源的Yosys。我两个都用过,说说我的感受。

特性 Design Compiler (DC) Yosys
商业/开源 商业,价格昂贵 开源,免费
工艺库支持 全工艺库(TSMC、SMIC等) 主要支持标准单元库,部分先进工艺需适配
优化能力 强,时序驱动综合 中等,适合教学和简单设计
输出格式 Verilog网表、DDC、SDC Verilog网表、BLIF、JSON
脚本语言 dc_shell-tcl Yosys脚本(类似Tcl)

我在项目中遇到过用DC综合一个复杂的SoC,跑了整整两天。而Yosys呢?我拿它做逆向分析时,几秒钟就出网表了。各有各的用途。

3.3 DC综合实战:一个简单的例子

假设我们有这样一个RTL模块:

module counter (
    input clk,
    input rst_n,
    input en,
    output reg [3:0] count
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            count <= 4'b0;
        else if (en)
            count <= count + 1;
    end
endmodule

用DC综合,我一般这么写脚本:

# 设置工艺库
set target_library "typical.db"
set link_library "* typical.db"

# 读入RTL
analyze -format verilog counter.v
elaborate counter

# 设置时序约束
create_clock -period 10 [get_ports clk]
set_input_delay 2 [get_ports en] -clock clk
set_output_delay 2 [get_ports count] -clock clk

# 综合
compile -map_effort high

# 输出网表
write -format verilog -hierarchy -output counter_synth.v
write_sdc counter.sdc

跑完之后,你会得到一个门级网表。里面不再是 count <= count + 1 这种RTL写法,而是:

DFF_X1 count_reg_0_ (.D(n1), .CK(clk), .Q(count[0]));
DFF_X1 count_reg_1_ (.D(n2), .CK(clk), .Q(count[1]));
// ... 还有一堆加法器、与门、或门

你看,DFF_X1 就是工艺库里的标准D触发器。X1表示驱动能力等级。

我的小技巧: 综合完成后,一定要检查一下 report_timingreport_area。我习惯把时序余量(slack)控制在0以上,如果出现负slack,说明你的设计跑不到目标频率,得回去改RTL或者调约束。

3.4 Yosys综合:开源党的选择

如果你在做逆向分析或者学术研究,Yosys是首选。它轻量、透明,而且能输出多种格式的网表。

同样的计数器,用Yosys综合:

# 读取RTL
read_verilog counter.v

# 高层次综合(把RTL转成内部表示)
hierarchy -check
proc
opt

# 映射到标准单元库(这里用内置的simple库)
techmap
opt

# 输出网表
write_verilog counter_yosys.v

Yosys的输出网表长这样:

module counter (clk, rst_n, en, count);
  input clk, rst_n, en;
  output [3:0] count;
  wire [3:0] _0_;
  wire [3:0] _1_;
  // ... 内部连线
  $_DFF_P_ _2_ (.C(clk), .D(_0_[0]), .Q(count[0]));
  // ...
endmodule

注意看,Yosys用的内部单元名是 $_DFF_P_,而不是工艺库里的 DFF_X1。这是因为Yosys默认用内置的通用单元库。如果你想映射到真实工艺库,需要额外提供 .lib 文件。

避坑指南: 我曾经用Yosys综合一个带异步复位的设计,结果发现复位信号没被正确映射。后来查文档才知道,Yosys对异步复位的处理需要额外加 dfflegalize 命令。所以,用Yosys做严肃项目前,一定要先跑几个测试用例验证一下。

3.5 综合产物:你拿到了什么?

综合完成后,你会得到一堆文件。我列一下最重要的几个:

  • 门级网表(.v):这是核心产物,包含了所有标准单元的实例化和连线。
  • 时序约束文件(.sdc):记录了你的时钟周期、输入输出延迟等约束。后续的布局布线、静态时序分析都要用它。
  • 综合报告(.rpt):包括面积报告、时序报告、功耗报告。我每次都会仔细看面积报告,看看哪个模块占了多少面积,有没有异常大的。
  • DDC文件(DC特有):Synopsys的内部格式,保存了综合后的完整设计数据,方便后续工具读取。

嗯,这里要特别提醒:网表文件不要随便改!我见过有人手动修改网表来「优化」面积,结果导致功能错误。网表是工具生成的,人工干预风险极高。

3.6 知识体系:一张图看懂

下面这张SVG图,是我自己画的,把综合的整个流程串起来了。你一看就明白。

逻辑综合流程与产物 RTL代码(.v) 综合工具 DC / Yosys 门级网表(.v) 输出产物 网表文件(.v) 时序约束(.sdc) 综合报告(.rpt) DDC(DC特有) 图:从RTL到门级网表的综合流程及主要输出产物

这张图把整个流程浓缩了。你从左上角的RTL代码开始,经过综合工具(DC或Yosys),最终得到门级网表和一堆辅助文件。我建议你把这张图打印出来贴在工位上,每次做综合时对照着看,不容易漏步骤。

核心要点: 综合不是「一键生成」那么简单。它需要你理解工艺库、设置正确的约束、检查报告。我见过太多人把综合当成黑盒子,结果流片回来才发现问题。记住:综合工具只是工具,真正的决策者是你自己。

好了,这一章就到这里。下一章我们会深入网表的结构,看看门级网表里到底藏着什么秘密——这对逆向分析来说,是基本功。


公众号:蓝海资料掘金营,微信deep3321