3、设计输入:理解RTL到GDSII的流程、设计数据准备

好,咱们进入第三章。说实话,很多初学者一上来就急着跑Flow,结果卡在最开始的数据准备上。我见过不少项目,因为一个文件格式不对,整个团队等了两天。所以这一章,咱们把“输入”这件事彻底聊透。

3.1 RTL到GDSII:一张图看懂全流程

先别管OpenROAD具体怎么用,你得先知道芯片设计从代码到光罩,到底经历了什么。我习惯把这过程分成四大阶段:前端逻辑设计、后端物理实现、验证签核、流片。OpenROAD主要覆盖的是后端物理实现这一块。

下面这张图,是我自己总结的“RTL到GDSII核心流程”,你把它存脑子里,后面学起来会顺很多。

RTL到GDSII核心流程 RTL → GDSII 核心流程 RTL 设计 (Verilog) 逻辑综合 门级网表 布图规划 (Floorplan) 布局 (Placement) 时钟树综合 (CTS) 布线 (Routing) 物理验证 GDSII 输出 输入文件:Verilog (.v) + SDC (.sdc) + LEF (.lef) + DEF (.def) 前端 后端 签核

说白了,OpenROAD就是帮你把中间那几大步(布图、布局、CTS、布线)自动化跑通。但前提是——你得把“原料”准备好。

3.2 设计数据准备:三大核心文件

我个人习惯把输入文件分成三类:逻辑描述、时序约束、物理库。缺一个,流程就跑不起来。

文件类型 扩展名 内容 谁生成
Verilog .v 门级网表(综合后) 逻辑综合工具
SDC .sdc 时序约束(时钟、IO延迟) 前端设计工程师
LEF .lef 工艺库(单元尺寸、引脚位置) 晶圆厂/PDK
DEF .def 设计交换(初始布局、电源网格) 布图规划/IO规划

3.2.1 Verilog:你的“电路图纸”

OpenROAD读入的Verilog,必须是综合后的门级网表。不是RTL代码!我刚开始用OpenROAD时犯过这个错,直接把RTL扔进去,结果工具报了一堆“undefined module”。

一个标准的门级网表长这样:

module top (clk, rst, data_in, data_out);
  input clk, rst;
  input [7:0] data_in;
  output [7:0] data_out;

  wire [7:0] net1;
  DFF_X1 ff1 (.D(data_in[0]), .CK(clk), .Q(data_out[0]));
  // ... 其他标准单元例化
endmodule
我的习惯:在综合时,把“-no_autoungroup”选项打开。这样网表层次清晰,OpenROAD做物理优化时不容易乱。

3.2.2 SDC:给芯片定“规矩”

SDC文件定义了你的芯片要跑多快。没有它,OpenROAD不知道该怎么优化。我见过最惨的案例,就是SDC里忘了约束异步时钟域,结果芯片流片回来,跨时钟域的数据全是乱的。

核心约束就这几条:

# 创建时钟
create_clock -name clk -period 10.0 [get_ports clk]

# 输入延迟
set_input_delay -max 2.0 -clock clk [get_ports data_in]

# 输出延迟
set_output_delay -max 3.0 -clock clk [get_ports data_out]

# 伪路径(异步时钟域)
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]
注意:OpenROAD的STA引擎(OpenSTA)对SDC的语法支持很严格。别用那些商业工具特有的命令,比如“set_clock_uncertainty”在某些版本里会报错。我建议你跑之前,先用“read_sdc -echo”检查一遍。

3.2.3 LEF/DEF:物理世界的“地图”

LEF是工艺库的抽象视图。它告诉工具每个标准单元有多大、引脚在哪层、走线规则是什么。DEF则是你的设计在物理空间上的初始布局。

这两者配合使用。LEF是“字典”,DEF是“文章”。

  • LEF文件:通常由晶圆厂提供,包含所有标准单元、宏单元、IO单元的物理信息。
  • DEF文件:在布图规划阶段生成,定义了芯片尺寸、IO位置、电源网络、以及初始的单元摆放。

OpenROAD读入LEF/DEF的顺序有讲究。我建议:

  1. 先读LEF(工艺库)
  2. 再读DEF(设计布局)
  3. 最后读Verilog(网表)

为什么?因为DEF里可能已经包含了某些单元的初始位置,后读Verilog可以确保网表和物理位置对应上。

3.3 OpenROAD的输入文件格式:别踩这些坑

OpenROAD对文件格式的要求,说白了就一个字:严。它不像商业工具那么“宽容”,格式不对直接报错退出。

文件 常见坑点 我的避坑方法
Verilog 模块名大小写敏感;未定义的cell 用“read_verilog -golden”检查
SDC 不支持Tcl过程;时钟名拼错 先用“report_clocks”确认
LEF 版本不匹配(5.7 vs 5.8) 统一用LEF 5.7格式
DEF 坐标单位不一致(micron vs 1000) 检查“UNITS DISTANCE”字段

核心原则:所有输入文件必须来自同一个PDK版本。我曾经因为LEF和Verilog的单元定义不一致,查了三天才找到问题——原来是PDK更新后,某个标准单元的引脚名变了。

3.4 一个完整的输入示例

假设你有一个设计叫“my_design”,在OpenROAD里加载它的标准流程是:

# 1. 读入LEF(工艺库)
read_lef /path/to/sky130_fd_sc_hd__lef_tech.lef
read_lef /path/to/sky130_fd_sc_hd__lef_cells.lef

# 2. 读入DEF(初始布局)
read_def /path/to/my_design.def

# 3. 读入Verilog(门级网表)
read_verilog /path/to/my_design.v

# 4. 读入SDC(时序约束)
read_sdc /path/to/my_design.sdc

# 5. 链接设计(把网表和物理库绑定)
link_design my_design

嗯,这里要注意:link_design这一步很容易被忽略。如果不做,后面所有操作都会报“design not linked”。我刚开始就吃过这个亏。

3.5 小结:数据准备清单

在你开始跑OpenROAD之前,对照这个清单检查一遍:

  • ✅ 门级网表(.v)—— 综合后,无未定义模块
  • ✅ 时序约束(.sdc)—— 时钟、IO延迟、伪路径都写了
  • ✅ 工艺LEF(.lef)—— 版本匹配,包含所有用到的单元
  • ✅ 设计DEF(.def)—— 坐标单位正确,IO位置已定义
  • ✅ 所有文件路径无中文、无空格