2. 设计导入与初始化

在 Fusion Compiler 中,设计导入与初始化是整个物理实现流程的起点,也是决定后续综合、布局、时钟树和布线能否顺利推进的关键环节。这一阶段的核心任务并不是简单地“把文件读进来”,而是把来自前端综合的网表、约束、功耗意图、工艺库和物理库组织成一个内部一致、可被工具正确解释的设计数据库。如果输入文件之间存在版本错配、单位不一致、库缺失或约束语法错误,问题往往不会立刻暴露,而是在布局或时序优化阶段以难以定位的形式出现。因此,导入阶段必须做到“读得进、认得清、查得出”。

一、需要导入的五类核心输入

Fusion Compiler 初始化通常围绕五类输入展开。第一类是门级网表,常见格式为 Verilog 或 VHDL,描述设计的逻辑连接关系,是后续所有物理操作的逻辑基础。第二类是SDC 约束文件,定义时钟、输入输出延迟、时序例外、多周期路径和伪路径等,决定工具如何判断时序是否满足。第三类是UPF 功耗意图文件,描述电源域、电源开关、隔离单元、电平转换器和保持寄存器的位置与策略,是多电压域设计必须导入的内容。第四类是物理库,包括标准单元库、宏单元库、I/O 库以及对应的物理抽象视图,提供单元的版图尺寸、引脚位置和布线层信息。第五类是工艺文件,通常包含 TLU+ 寄生参数模型、层定义、通孔规则和金属堆叠信息,用于后续的寄生提取与时序计算。

这五类输入之间并非彼此独立。网表中的单元必须能在物理库中找到对应实现;SDC 中引用的时钟端口必须存在于网表;UPF 中声明的电源域必须与网表层次和库中的电源引脚一致;工艺文件中的层信息必须与物理库中单元的引脚层匹配。任何一处不一致,都会在初始化检查中留下隐患。

Fusion Compiler 设计导入与初始化数据流 输入文件 门级网表 .v / .vg SDC 约束 .sdc UPF 功耗意图 .upf 物理库 .db / .lef / .lib 工艺文件 TLU+ / 层定义 初始化处理 read_verilog 链接逻辑库 read_sdc 时钟/IO/例外 load_upf 电源域/隔离 set_tlu_plus_files 寄生参数模型 初始化检查 check_design 未解析引用 / 悬空端口 check_timing 未约束端点 / 时钟冲突 check_mv_design 电源域 / 隔离 / 电平转换 report_lib 库版本 / 单元完整性 report_units 时间 / 电容 / 电阻单位 通过 → 进入综合/布局 五类输入经初始化处理形成统一设计数据库,检查通过后方可进入物理实现主流程

二、初始化脚本的组织方式

实际项目中,导入过程通常写成一个可复用的初始化脚本,而不是在交互界面逐条输入。一个典型的 Fusion Compiler 初始化脚本结构如下:

# 设置搜索路径与库变量
set search_path [list ./libs ./rtl ./sdc ./upf]
set target_library [list sc9_cln40_ssg_0p99v_125c.db]
set link_library   [list * sc9_cln40_ssg_0p99v_125c.db \
                         sram_2048x32_ssg_0p99v_125c.db]

# 读取物理库与工艺文件
read_lef  ./libs/sc9_cln40_6lm.lef
read_lef  ./libs/sram_2048x32.lef
set_tlu_plus_files -max_tluplus ./tech/40nm_max.tluplus \
                   -min_tluplus ./tech/40nm_min.tluplus \
                   -tech2itf_map ./tech/tech2itf.map

# 读取网表并链接
read_verilog ./rtl/top_netlist.v
current_design top
link

# 读取约束与功耗意图
read_sdc ./sdc/top_func.sdc
load_upf ./upf/top_power.upf

# 单位一致性确认
report_units

# 初始化检查
check_design  > ./rpt/check_design.rpt
check_timing  > ./rpt/check_timing.rpt
check_mv_design > ./rpt/check_mv.rpt
report_lib    > ./rpt/report_lib.rpt

这段脚本体现了导入阶段的基本顺序:先建立库和工艺环境,再读网表并链接,然后施加约束和功耗意图,最后统一做检查。顺序不能随意颠倒,例如在 link 之前读取 SDC,工具可能因为找不到设计对象而报错;在设置 TLU+ 之前做时序检查,寄生参数不完整会导致结果失真。

三、初始化检查的关键判据

导入完成后,必须通过几项检查来确认设计数据库是“干净”的。check_design 主要报告未解析的模块引用、悬空输入端口、多驱动网络和常量冲突。如果网表中例化了某个宏单元,但 link_library 中没有对应 .db,工具会把它标记为 unresolved reference,此时必须补齐库或修正网表,不能带着黑盒进入布局。check_timing 用于发现未约束的时序端点、没有时钟定义的寄存器、时钟之间的冲突以及输入输出延迟缺失。一个常见现象是:SDC 中只定义了功能时钟,但扫描链端口没有设置 false path,导致工具在扫描模式下过度优化。此时应补充 set_case_analysis 或 set_false_path,而不是忽略报告。

对于多电压设计,check_mv_design 会检查电源域边界是否缺少隔离单元、跨域信号是否缺少电平转换器、保持寄存器是否被正确识别。UPF 中声明的电源域必须与网表层次一致,例如 UPF 写的是 top/u_core,而网表中实际层次为 top/u_cpu_core,工具就无法把电源域正确绑定到实例上。这类问题在 check_mv_design 中通常表现为 “domain not found” 或 “no isolation strategy applied”。

此外,report_units 用于确认时间单位、电容单位和电阻单位。网表、SDC、库和 TLU+ 文件如果单位不一致,会出现时序数量级错误。例如库以 ns 为单位,而 SDC 以 ps 书写,工具可能把 1 ns 当成 1 ps 处理,导致时序报告完全不可信。初始化阶段必须显式核对单位,而不是默认它们一致。

四、常见问题与处理思路

导入阶段最常见的问题可以归纳为三类。第一类是库缺失或版本错配:网表使用了某个标准单元,但 target_library 中没有该单元,或者库的版本与网表综合时使用的版本不同。处理方式是核对综合报告中的库列表,确保物理实现使用的库与综合一致。第二类是约束不完整:SDC 中缺少 generated clock 定义、缺少输入输出延迟、或者时钟名称与网表端口不匹配。处理方式是先用 check_timing 定位未约束对象,再回到 SDC 中补充。第三类是UPF 与网表层次不一致:电源域、电源开关或隔离策略引用了不存在的实例或端口。处理方式是逐条核对 UPF 中的层次路径与网表实例名,必要时用 get_cells 在工具中验证对象是否存在。

初始化检查报告不要只看“有没有 error”,还要关注 warning。很多 warning 在导入阶段看似无害,但会在布局或时序优化阶段放大为难以定位的问题。建议把 check_design、check_timing、check_mv_design 和 report_lib 的输出统一保存到 rpt 目录,作为后续排障的基线。

五、一个可复用的初始化检查清单

检查项 命令/方法 通过判据
网表链接完整性 link + check_design 无 unresolved reference,无悬空端口
时序约束覆盖 check_timing 无 unconstrained endpoint,时钟定义完整
功耗意图绑定 check_mv_design 电源域、隔离、电平转换策略均匹配
库与单元一致性 report_lib 所有例化单元均可在库中找到
单位一致性 report_units 时间/电容/电阻单位与库、SDC 一致
工艺文件加载 set_tlu_plus_files max/min TLU+ 与 layer map 均成功读取

完成上述导入与检查后,设计数据库才具备进入综合优化和物理布局的条件。初始化阶段投入的时间,通常会在后续阶段以更少的返工和更清晰的排障路径得到回报。把输入读对、把约束读全、把库和工艺读准,是 Fusion Compiler 物理实现流程中第一件必须做扎实的事。