1. Design Compiler综合流程与约束驱动方法
Design Compiler(简称DC)是Synopsys推出的RTL综合工具,它的核心任务是把可综合的寄存器传输级(RTL)代码,在工艺库和目标约束的共同作用下,转换成门级网表。理解DC的综合流程,关键不在于记住几条命令,而在于理解“约束如何驱动优化”:同一份RTL,在不同时钟周期、不同输入延迟、不同面积目标下,会综合出面积、时序、功耗差异很大的电路。约束不是综合之后的检查项,而是综合过程的输入条件。
一、DC综合的完整流程
DC的一次完整综合,通常包含五个阶段:读入设计、施加约束、编译优化、报告分析、输出结果。这五个阶段不是单向流水线,报告分析发现问题后往往要回到约束或RTL修改,形成迭代闭环。
读入设计阶段,DC需要三类输入:RTL源码、工艺库、以及可选的综合脚本。RTL通过 analyze 与 elaborate 两步进入DC内存:analyze 负责语法检查并生成中间格式,elaborate 负责展开参数、推断寄存器与组合逻辑,建立设计的层次结构。工艺库通过 target_library、link_library 指定,前者是综合映射用的标准单元库,后者是解析实例引用的库集合。
施加约束阶段是约束驱动方法的核心。时钟用 create_clock 定义,输入输出延迟用 set_input_delay、set_output_delay 描述,组合路径用 set_max_delay 约束,工作环境用 set_operating_conditions、set_load、set_driving_cell 描述。此外还要用 set_max_area 给出面积目标,用 set_dont_touch 保护特定单元或模块。
编译优化阶段由 compile 或 compile_ultra 执行。DC会先做结构优化(资源共享、公共子表达式提取),再做逻辑优化(布尔化简、映射),最后做门级优化(缓冲插入、单元尺寸调整、路径重组)。每一步都在约束边界内寻找更优解。
报告分析阶段用 report_timing、report_area、report_constraint、report_qor 查看时序、面积、约束违例。时序报告中的slack是判断依据:slack为正表示满足,为负表示违例,负值大小反映违例严重程度。
输出结果阶段用 write 命令导出网表(write -format verilog)、SDC约束(write_sdc)、以及供后续工具使用的DB文件(write -format db)。
二、约束如何驱动综合优化
约束驱动优化的本质,是DC把约束翻译成“成本函数”,在满足约束的前提下最小化面积或功耗。以时钟约束为例:create_clock -period 10 [get_ports clk] 告诉DC,所有从clk出发的时序路径必须在10ns内完成。DC会据此计算每条路径的到达时间与要求时间,得到slack。若某条路径slack为负,DC会尝试用更快的单元、插入缓冲、重组逻辑来修复;若所有路径slack都为正且余量很大,DC会反过来缩小单元尺寸以节省面积。
输入输出延迟约束同样关键。set_input_delay -clock clk 3 [get_ports data_in] 表示外部信号在时钟沿后3ns才到达端口,DC必须把这段延迟算进路径预算。如果这个值设得过大,DC会认为内部逻辑可用时间很少,从而过度优化;设得过小,则可能综合出实际无法满足的电路。因此约束值必须来自真实的系统时序预算,而不是随手填写。
set_max_delay 和 set_min_delay 会覆盖时钟推导出的默认约束;set_false_path 和 set_multicycle_path 用于排除或放宽特定路径,避免DC在不必要的路径上浪费优化资源。三、DC启动方式与基本命令
DC有两种常用启动方式。交互式启动直接输入 dc_shell,适合调试和逐步探索;批处理启动使用 dc_shell -f script.tcl,适合回归和自动化。无论哪种方式,都建议用Tcl脚本组织命令,便于版本管理和复现。
一个典型的综合脚本骨架如下:
# 设置库
set target_library "sc9_cln40ll_base_tt_1p1v25c.db"
set link_library "* $target_library"
# 读入设计
analyze -format verilog {./rtl/top.v ./rtl/alu.v}
elaborate top -architecture verilog
# 施加约束
create_clock -period 10 -name clk [get_ports clk]
set_input_delay -clock clk 3 [get_ports data_in]
set_output_delay -clock clk 2 [get_ports data_out]
set_max_area 0
# 编译
compile_ultra -gate_clock
# 报告
report_timing -max_paths 10 > timing.rpt
report_area > area.rpt
report_constraint -all_violators > violators.rpt
# 输出
write -format verilog -hierarchy -output ./netlist/top.v
write_sdc ./netlist/top.sdc
write -format db -hierarchy -output ./netlist/top.db
这段脚本中,set_max_area 0 表示面积不设上限,让DC优先满足时序;compile_ultra -gate_clock 在优化同时插入门控时钟以降低功耗。report_constraint -all_violators 是排查问题的第一入口,它会列出所有未满足的约束,包括时序、面积、设计规则违例。
四、结果判读与迭代
综合完成后,首先要看 report_qor 给出的整体质量指标,包括WNS(最差负slack)、TNS(总负slack)、违例路径数、总面积。WNS为负说明有时序违例,需要回到约束或RTL定位;WNS为正但面积远超预期,说明约束过紧或优化策略偏保守。
定位时序违例时,用 report_timing -max_paths 20 -nworst 5 查看最差路径的起点、终点、经过的逻辑级数和每级延迟。如果违例集中在某几条路径,优先检查这些路径是否被误设为false path或multicycle path;如果违例分散且逻辑级数很深,可能需要调整RTL的流水线结构,而不是单纯加约束。
掌握DC综合流程的关键,是把“读入—约束—编译—报告—输出”看作一个以约束为中心的闭环。约束定义优化目标,编译在目标内搜索解,报告暴露差距,迭代修正约束或RTL。只有理解这条驱动链,才能让DC真正按设计意图工作,而不是产出一个“能跑但不可用”的网表。