RTL代码综合与网表分析实战 - 第1节

一、综合概述:什么是逻辑综合

大家好,我是老李。做数字IC设计十几年了,今天咱们聊聊综合这件事。

逻辑综合,说白了就是把你的RTL代码翻译成门级网表。你写的是always块、assign语句,综合工具把它变成与门、或门、触发器这些东西。嗯,就这么简单。

我记得刚入行那会儿,有个老工程师跟我说:「小李啊,你写的代码最终是要变成硅片的,不是让你在纸上画着玩的。」当时不太理解,后来做了几个项目才明白——综合就是连接你写的代码和实际芯片的那座桥。

核心定义:逻辑综合是将RTL(寄存器传输级)描述转换为门级网表的过程,同时满足时序、面积、功耗等约束条件。

综合在数字IC设计流程中的位置

整个数字IC设计流程,我习惯把它分成三个阶段:前端设计、综合实现、后端物理设计。综合正好卡在中间,承上启下。

你想想看,前端你写好了RTL代码,做了功能仿真,验证了逻辑正确性。但这时候的代码还是「软」的,没法直接拿去流片。综合就是把这个「软」的东西变「硬」的第一步。

典型设计流程中的综合位置

RTL设计 Verilog/VHDL 功能仿真 验证逻辑正确性 逻辑综合 RTL → 门级网表 门级仿真 网表功能验证 STA静态时序分析 时序约束检查 后端物理设计 布局布线 流片 Tape-out 前端设计 后端设计

这张图是我自己画的,你看综合的位置,前面连着RTL和仿真,后面接着门级仿真和STA。综合做得好不好,直接决定了后端能不能顺利跑下去。

个人经验:我建议你在综合之前,先把RTL代码的仿真覆盖率做到95%以上。不然综合出来的网表出了问题,你都不知道是代码写错了还是综合工具没用好。

综合的输入与输出

综合的输入,说白了就三样东西:RTL代码、工艺库、约束文件。缺一不可。

输入一:RTL代码

就是你写的Verilog或VHDL。这里有个坑——不是所有能仿真的代码都能综合。我曾经见过一个同事,写了满屏的#10延时,仿真跑得欢,一综合就报错。嗯,综合工具只认可综合的语法。

输入二:工艺库

工艺库是foundry提供的,里面包含了标准单元的各种信息:

  • 每个门的延迟参数
  • 面积信息
  • 功耗数据
  • 驱动能力

说白了,工艺库就是综合工具的「零件手册」。没有它,工具不知道用什么元件来搭你的电路。

输入三:约束文件

约束文件告诉综合工具你的设计目标是什么。最常见的约束包括:

  • 时钟频率(比如你要跑200MHz还是500MHz)
  • 输入输出延迟
  • 面积上限
  • 功耗预算

注意:约束文件不是随便写写的。我曾经接手过一个项目,前工程师把时钟约束设得太松,综合出来的网表时序一塌糊涂,后端怎么修都修不回来。最后只能重新综合,浪费了两周时间。

综合的输出

综合完,你会得到这些东西:

输出文件 说明 后缀名举例
门级网表 由标准单元组成的电路连接描述 .v, .vg
时序报告 各路径的建立时间、保持时间检查结果 .rpt
面积报告 综合后的芯片面积统计 .area.rpt
功耗报告 动态功耗和静态功耗估算 .power.rpt
SDC约束文件 综合后的时序约束,供后端使用 .sdc

这里我要多说一句:网表文件是综合最核心的输出。它长什么样呢?给你看个例子:

// 综合后的网表示例
module counter (clk, rst_n, en, count);
  input  clk, rst_n, en;
  output [3:0] count;
  
  wire n1, n2, n3;
  wire [3:0] count_int;
  
  DFFRQ_X1 count_reg_0_ (.D(n1), .CK(clk), .RN(rst_n), .Q(count[0]));
  DFFRQ_X1 count_reg_1_ (.D(n2), .CK(clk), .RN(rst_n), .Q(count[1]));
  DFFRQ_X1 count_reg_2_ (.D(n3), .CK(clk), .RN(rst_n), .Q(count[2]));
  DFFRQ_X1 count_reg_3_ (.D(count_int[3]), .CK(clk), .RN(rst_n), .Q(count[3]));
  
  // ... 组合逻辑部分省略
endmodule

你看,原来你写的always块,现在变成了具体的DFFRQ_X1触发器。X1表示驱动能力等级,这是工艺库里定义好的。

关键点:综合输出的网表是「工艺相关」的。同样的RTL代码,用不同的工艺库综合,出来的网表完全不一样。所以换工艺节点时,一定要重新综合。

综合的本质是什么

说了这么多,综合的本质其实就是一件事:映射。把行为级的描述映射到结构级的实现。

你写了一个加法器:

assign sum = a + b;

综合工具会去工艺库里找,看看有没有现成的加法器单元。如果有,直接例化。如果没有,就用全加器和半加器搭一个。这个过程,工具会自动完成。

但我得提醒你,工具不是万能的。你写的代码风格直接影响综合结果。比如:

  • 组合逻辑写得太深,时序容易出问题
  • if-else写得不完整,会综合出锁存器
  • case语句没写default,也会出锁存器

避坑指南:我曾经因为一个case语句漏了default,综合出来一堆锁存器,面积大了30%。从那以后,我写case必带default,写if-else必带else。这个习惯救了我很多次。

好了,关于综合的概述就聊到这儿。记住一句话:综合是连接你写的代码和实际芯片的桥梁。桥搭得好不好,直接决定了你的芯片能不能跑起来。

可可精品资料库