3. Design Compiler综合自动化基础
Design Compiler(DC)的综合过程本质上是一系列 Tcl 命令按特定顺序作用于设计对象的过程。手工在交互式 shell 中逐条敲命令只适合探索,真正可交付的综合流程必须固化为脚本。一个可维护的 DC 综合脚本通常由四段构成:环境与库设置、设计读入与链接、约束施加、编译与报告输出。理解这四段之间的依赖关系,比记住某条命令的选项更重要。
脚本骨架与变量组织
环境设置段负责告诉 DC“用什么工艺、去哪里找库”。典型写法是设置 search_path、target_library、link_library、symbol_library 与 synthetic_library。其中 target_library 决定综合映射到的标准单元库,link_library 用于解析实例引用,通常需要把 * 放在最前以优先解析当前设计。为避免路径硬编码,建议把工程根目录、库目录、结果目录抽成变量:
set PRJ_ROOT /proj/uart_ctrl
set LIB_DIR $PRJ_ROOT/lib
set RPT_DIR $PRJ_ROOT/rpt
set NET_DIR $PRJ_ROOT/netlist
set search_path [list . $LIB_DIR $RPT_DIR]
set target_library "sc9_cln40lp_tt_1v0_25c.db"
set link_library "* $target_library dw_foundation.sldb"
set symbol_library "sc9_cln40lp.sdb"
set synthetic_library "dw_foundation.sldb"
把库名、时钟周期、输入输出延迟等参数集中定义在脚本头部,后续命令只引用变量,是脚本可复用的关键。例如 set CLK_PERIOD 2.5、set IN_DELAY 0.8、set OUT_DELAY 0.6,当工艺或频率目标变化时只需改一处。
设计读入与链接
读入阶段常用 analyze -format verilog 配合 elaborate,或直接用 read_verilog。区别在于 analyze 会生成中间格式并支持增量,适合多文件工程;elaborate 负责展开参数、解析层次并建立设计对象。链接用 link 检查所有实例是否能在 link_library 中找到,未解析的引用会在此阶段报 warning,必须清零后再进入约束阶段。常用检查命令是 check_design,它会报告悬空端口、多驱动、组合环等问题。
时序与面积约束
约束是综合质量的分水岭。时序约束的核心是时钟定义与 I/O 边界条件。以 2.5 ns 周期时钟为例:
create_clock -name clk -period $CLK_PERIOD [get_ports clk]
set_clock_uncertainty 0.15 [get_clocks clk]
set_clock_transition 0.10 [get_clocks clk]
set_input_delay $IN_DELAY -clock clk [remove_from_collection [all_inputs] [get_ports clk]]
set_output_delay $OUT_DELAY -clock clk [all_outputs]
set_driving_cell -lib_cell BUFFD2BWP -pin Z [all_inputs]
set_load 0.05 [all_outputs]
这里 set_clock_uncertainty 为时钟抖动与偏斜预留余量,set_driving_cell 与 set_load 描述真实驱动与负载,避免 DC 用理想环境估算出过于乐观的时序。面积约束用 set_max_area 给出上限,但更推荐用 set_max_area 0 让工具在满足时序前提下尽量优化面积,再通过报告评估。此外还需处理 set_false_path、set_multicycle_path 等例外,例如跨异步时钟域路径应设为 false path,否则会引入无意义的优化压力。
约束施加后必须用 check_timing 验证:未约束端点、无时钟寄存器、组合反馈等都会在此暴露。一个常见错误是只约束了时钟却忘了 I/O delay,导致边界路径被当作零延迟处理,综合结果与后端严重不符。
编译与报告自动生成
编译用 compile_ultra,可加 -gate_clock 启用门控时钟、-retime 做寄存器重定时。编译完成后进入报告阶段,这是自动化脚本最容易被忽视却最有价值的部分。建议至少生成四类报告:时序报告 report_timing、面积报告 report_area、约束违例报告 report_constraint -all_violators、功耗报告 report_power。用 redirect 把输出写入文件:
redirect $RPT_DIR/timing.rpt { report_timing -max_paths 20 -nworst 5 -delay max }
redirect $RPT_DIR/area.rpt { report_area -hierarchy }
redirect $RPT_DIR/viol.rpt { report_constraint -all_violators -verbose }
redirect $RPT_DIR/power.rpt { report_power -analysis_effort high }
write -format verilog -hierarchy -output $NET_DIR/uart_ctrl_syn.v
write_sdc $NET_DIR/uart_ctrl.sdc
报告生成后应做自动判读,而不是靠人翻文件。可在 Tcl 中提取关键指标并打印汇总行,例如用 get_attribute 读取 slack,或对 report_constraint 的输出做文本匹配统计违例条数。若 WNS(最差负裕量)小于 0 或违例数大于阈值,脚本应返回非零退出码,让上层 CI 流程感知失败。