DC(Design Compiler)基础:启动、脚本与库配置
各位同学,咱们今天聊聊DC。Design Compiler,Synopsys家的逻辑综合工具,可以说是数字IC设计流程里最核心的一环。我当年刚入行时,觉得DC就是个黑盒子,把RTL代码扔进去,出来个网表就完事了。后来踩了不少坑才明白——DC的启动方式、脚本写法、库文件配置,每一个细节都直接影响最终芯片的时序和面积。
好,咱们直接进入正题。
DC的启动与工作模式
DC的启动,说白了就两种方式:命令行模式和图形界面模式。我个人习惯用命令行,因为方便批量跑、方便集成到自动化流程里。但调试初期,图形界面确实更直观。
命令行模式
直接在终端敲:
dc_shell -f run.tcl
或者进入交互模式:
dc_shell
然后一条条敲命令。嗯,这里要注意,dc_shell启动后默认是dc_shell-t模式,支持TCL语法。如果你用的是老版本,可能需要加-tcl参数。
图形界面模式
启动命令:
design_vision
或者从dc_shell里敲:
gui_start
图形界面适合看综合后的电路结构、查路径、看报告。但我建议你,脚本一定要写在文件里,不要依赖鼠标点来点去。为什么?因为项目迭代时,你不可能每次都重新点一遍。
工作模式
DC有几种工作模式,我简单列一下:
- Topographical模式:这是目前最常用的模式。它能在综合阶段就预估物理布局的线负载,时序精度高很多。我建议新项目一律用这个模式。
- Wire Load模式:老模式了,靠统计模型估算线负载。小芯片还能凑合,先进工艺下误差太大。
- DC Expert模式:提供更多底层控制选项,适合高级用户做精细优化。
启动topographical模式很简单,在脚本开头加一句:
set_app_var synlib_wire_load_mode topographical
DC的TCL脚本基础
DC的脚本语言是TCL(Tool Command Language)。说白了,TCL就是一种胶水语言,把DC的各种命令串起来。你不需要精通TCL,但几个基本语法必须掌握。
变量与赋值
set clk_period 10
set clk_name "clk_core"
用$引用变量:
create_clock -name $clk_name -period $clk_period [get_ports clk]
列表操作
DC里经常要处理多个库、多个文件:
set search_path [list . /home/libs /home/scripts]
set my_libs [list slow.lib fast.lib]
遍历列表:
foreach lib $my_libs {
echo "Processing $lib"
}
条件判断
if { [get_ports -quiet rst_n] != "" } {
set_driving_cell -lib_cell INVX1 [get_ports rst_n]
} else {
echo "Warning: rst_n port not found"
}
过程(函数)
把重复操作封装起来:
proc setup_clocks {period name port} {
create_clock -name $name -period $period [get_ports $port]
set_clock_uncertainty 0.1 [get_clocks $name]
set_clock_transition 0.05 [get_clocks $name]
}
避坑指南: 我曾经在脚本里忘了加-quiet参数,结果某个端口不存在时,DC直接报错退出。加上-quiet后,它会返回空字符串,你就可以用条件判断来处理了。
DC的库文件配置
库文件配置是DC综合的基础。配置错了,综合出来的网表可能根本不能用。我见过不少新手,库路径写错了,结果DC报了上千条warning,还以为是代码问题。
DC有三个核心库变量:target_library、link_library、synthetic_library。咱们一个一个说。
target_library
这是综合的目标库。DC会从这些库里挑选标准单元来映射你的设计。说白了,就是你要用哪些工艺库里的门电路。
set target_library [list slow.db fast.db]
注意:.db是Synopsys的二进制库格式,由.lib文件通过library_compiler生成。你直接给.lib文件也行,但DC每次启动都要重新编译,慢得很。
link_library
这个变量告诉DC,在链接阶段去哪里找设计中用到的所有模块。包括:
- 标准单元库(通常和target_library一样)
- IP库(比如SRAM、PLL)
- 自己写的子模块(如果已经综合成网表)
set link_library [list * $target_library ip_lib.db]
那个*号很关键,它表示“已经加载到内存中的设计”。不加的话,DC可能找不到你当前设计里的子模块。
注意: 我曾经犯过一个低级错误——link_library里忘了加*,结果DC报了一堆“Undefined module”错误。排查了半天,才发现是这个问题。嗯,这种坑踩过一次就记住了。
synthetic_library
这个变量用于指定综合库,主要是DesignWare库。DesignWare是Synopsys提供的可综合IP库,比如加法器、乘法器、FIFO等。
set synthetic_library [list dw_foundation.sldb]
如果你在代码里用了DesignWare的运算符(比如+、*),DC会自动调用对应的DW单元。但如果你用了DW的特定组件(比如DW_fifo),就必须显式指定synthetic_library。
完整的库配置示例
set search_path [list . /home/techlibs /home/designware]
set target_library [list tcbn28hpcplusbwp7t40lvt.db]
set link_library [list * $target_library]
set synthetic_library [list dw_foundation.sldb]
# 告诉DC使用topographical模式
set_app_var synlib_wire_load_mode topographical
小结
今天咱们聊了DC的启动方式、TCL脚本基础、以及库文件配置。这些东西看起来琐碎,但都是基本功。你想想看,如果库路径配错了,后面所有的综合结果都是错的,时序分析更是无从谈起。
下一章,咱们会深入讲DC的时序约束——这才是综合的灵魂。到时候我会分享一些实际项目里遇到的时序收敛案例,保证让你有收获。
个人建议: 刚开始学DC时,别急着跑大设计。先搭一个最小系统——比如一个计数器、一个加法器,把启动、库配置、综合、报告生成整个流程跑通。这样以后遇到复杂设计,你心里就有底了。