2. 设计对象与工作环境配置

在真正执行 compile 之前,Design Compiler 必须先"认识"你的设计。DC 内部并不是直接操作 Verilog 源文件,而是把设计抽象成一组有明确层次关系的对象(object)。理解这些对象以及它们之间的引用关系,是读懂后续所有约束命令、报告和报错信息的前提。本节先梳理 DC 的设计对象模型,再动手配置工作环境,最后完成一个简单设计的读入与链接。

一、DC 的设计对象模型

DC 把设计数据库中的一切建模为对象,最常用的几类如下:

  • design(设计):一个模块或实体的抽象,对应 Verilog 中的 module。它可以是当前正在综合的设计,也可以是被例化的子设计。
  • cell(单元):design 的一次实例化,对应 Verilog 中的实例。同一个 design 可以被例化多次,产生多个 cell。
  • port(端口):design 边界上的输入/输出接口,是模块与外界交换信号的通道。
  • pin(引脚):cell 上的连接点,对应被例化 design 的 port 在该实例上的映射。
  • net(连线):连接 port、pin 的物理/逻辑连线,承载信号。
  • clock(时钟):一种特殊的对象,由 create_clock 在指定 port 或 pin 上创建,是时序约束的基准。

它们的关系可以这样理解:design 是"类型",cell 是"实例";port 属于 design,pin 属于 cell;net 把 port 和 pin 连起来;clock 则依附在某个 port 或 pin 上,为整条时序路径提供参考。DC 中几乎所有命令都通过对象名来定位操作目标,例如 get_ports clk、get_cells U1、get_pins U1/A、get_nets n1。掌握这套对象命名与查询方式,才能写出准确的约束。

DC 设计对象关系示意 design: top port clk port a port b port y cell: U1 design: adder pin: A / B / S cell: U2 design: dff pin: D / CK / Q net n1 clock 对象 create_clock -period 10 [get_ports clk] 依附于 port clk,作为时序基准 所有时序路径以它为参考 对象引用关系 design → cell(类型→实例) design → port;cell → pin net 连接 port 与 pin clock 依附 port / pin

二、环境变量配置

DC 启动后需要知道"去哪里找设计文件""用哪个工艺库做映射""链接时用哪些库"。这些都由环境变量控制,通常在 .synopsys_dc.setup 中设置,DC 启动时会自动读取当前目录和用户主目录下的该文件。

search_path:告诉 DC 到哪些目录下查找源文件、库文件。它是一个目录列表,DC 按顺序搜索。

set search_path [list . ./rtl ./lib /project/tech/synopsys]

target_library:综合映射阶段的目标工艺库,DC 会把设计中的逻辑映射成该库中的标准单元。它决定了最终网表用什么单元实现。

set target_library [list slow.db]

link_library:链接阶段用于解析设计引用的库。除了工艺库,通常还要加上 "*",表示当前已读入内存的设计,否则 DC 找不到已读入的子模块。

set link_library [list "*" slow.db]

symbol_library:符号库,供 Design Vision 等图形界面显示单元符号使用,命令行综合不强制需要,但建议配置。

set symbol_library [list slow.sdb]
target_library 与 link_library 的区别是初学者最容易混淆的点:target_library 决定"映射成什么",link_library 决定"链接时去哪里找"。link_library 中的 "*" 不可省略,否则读入多个文件后无法互相解析。

三、读入与链接一个简单设计

下面以一个两级结构为例:顶层 top 例化了一个 adder 和一个 dff。假设文件为 top.v、adder.v、dff.v,均位于 ./rtl。

# 1. 读入所有源文件
read_verilog {./rtl/top.v ./rtl/adder.v ./rtl/dff.v}

# 2. 指定当前设计
current_design top

# 3. 链接设计,解析所有引用
link

# 4. 检查链接结果
check_design

read_verilog 只是把源文件解析成 DC 内部的设计对象,此时子模块可能还是"空壳"。link 的作用是把 top 中例化的 adder、dff 与已读入的 design 对应起来,并解析库单元引用。链接成功后,用 list_designs 可以看到 top、adder、dff 三个 design;用 get_cells 可以列出 U1、U2 两个 cell。

判断链接是否成功,主要看两点:一是 check_design 没有报 unresolved reference;二是 report_hierarchy 能完整展开层次。如果出现 Unable to resolve reference 'adder',通常是文件没读入、模块名拼写不一致,或 link_library 缺少 "*"。此时可用 list_designs 确认内存中到底有哪些 design,再回到 read_verilog 或 link_library 排查。

链接失败时不要急着写约束。约束命令依赖对象存在,若 design 未链接,get_cells、get_pins 会返回空,后续约束会静默失效或报错,问题被掩盖到综合阶段才暴露。

四、对象查询与验证

链接完成后,建议用一组查询命令确认对象模型是否符合预期,这也是后续写约束的常用手段:

命令作用示例输出
list_designs列出内存中所有 designtop adder dff
get_cells查询 cell 实例U1 U2
get_ports查询顶层 portclk a b y
get_pins查询 cell 引脚U1/A U1/B U1/S
get_nets查询连线n1 n2

这些命令返回的是对象集合,可以直接作为其他命令的参数,例如 create_clock -period 10 [get_ports clk]。理解"命令操作对象、对象由查询命令获得"这一模式,就掌握了 DC 脚本的基本写法。

至此,设计已经读入并链接完成,环境变量也已就位。下一步就可以在此基础上创建时钟、设置输入输出延迟,进入真正的约束与综合流程。