dc 查看命令帮助 ( 使用 man )
man
|
|
-help
|
|
help
|
|
列出所有以clock 结尾的命令
Design Compile (dc)常用命令
DC 综合基本步骤
DC 8类对象
dc 基础命令
获取对象的命令
- get_ports
- get_pins
- get_designs
- get_cells
- get_nets
- get_clocks
- all_inputs
- all_outputs
- all_clocks
- all_registers
analyze
把文件读入工程
analyze命令将设计转换成中间格式 *.mr,/.syn,/.st
读入过程中 analyze 会对输入文件进行语法错误及逻辑可综合性检查
若有错误则会有相应提示
elaborate
elaborate命令先检查analyze生成的中间格式,再将对象
转成内部数据格式*.db
通常和 analyze 成对使用
elaborate 后面加上一个模块的名字 则该模块被设置成顶层如:
elaborate b
- parameter
parameter 参数可以改变顶层中的参数 这是唯一一种通过命令行在读入design 的时候改变模块参数的方法如
:
elaborate top -parameter “WIDTH=4”
read
read命令和analyze与elaborate命令的不同是read命令
不进行语法检测只作格式翻译与优化
compile_ultra
高级的编译命令
- retime
这个选项可以让工具在优化的时候自由组合移动某些逻辑以达到优化timing 的作用 - incremental
增量编译
report_constraint
- all_violators
可以输出所有的时序违例
report_timing
输出时序路径的细节
- -delay max/min
max 输出 setup time min 输出 hold time - -from
起点 - -to
终点 - -through
经过哪些 pin port - -group
只输出该 group 的信息 - -input_pins
只输出输入引脚相关的信息 - -max_paths
指定只输出多少条最坏的时序路径信息 - -nworst
输出该端点上的最坏的几条时序路径信息 - -nets
输出 fanout 信息 - -capacitance
输出等效电容信息 - -significant_digits
设置输出精度 - 下图是 路径的Delay Time
如图 Incr 表示单个Cell 的时间延时 Path 表示整条路径上的延时 f 表示下降沿(falling)传输 r 表示上升沿(raising)传输 带*号的是 Net + Cell 的延时之和 - 下图是路径的 Required Time
其中 Clock uncertainty 即是 skew 时钟歪斜 最终要判断路径是否 meet 就是Slack = Data requried time - Data arrival time 如果为正则是 meet
report_area
报告面积 一般用于评估面积
report_port -verbose
get_cells
用法参考 man get_cells
get_clocks
用法参考 man get_clocks
get_designs
用法参考 man get_designs
get_libs
用法参考 man get_libs
get_lib_cells
用法参考 man get_libs_cells
get_nets
get_nets * 将列出所有nets
get_pins
get_pins * 将列出所有pins, get_pins 的正则不好用, 为了能快速的获得结果, 可以在综合前保存的网表文件中搜索到相关的寄存器, 然后直接写出路径
如上图所示, 要获得lead_ad_ck 的话可以使用 get_pins get_lead_inst/clk_lead/dac_clk_reg/Q
get_ports
get_ports 只能获取顶层的端口, 子模块的端口需要用get_pins 来获取
write
保存设计文件
保存所有设计约束和环境属性
|
|
保存用于反标注(back-annotation)的标准延时文件 (sdf => standard delay file)
|
|
将整个工程保存为 ddc 格式
|
|
将整个工程保存为 verilog 格式
|
|
如果只是想保存子模块的 ddc:
|
|
如果只是想保存子模块的 verilog:
|
|
ddc 格式是最全的格式 它会保存 design netlist, constraints and attributes
dc 库文件指定命令
指定元件库
set_app_var target_library .db
晶圆厂的器件库
指定符号库
set_app_var symbol_library .sdb
符号库主要用于显示原理图
指定连接库
set_app_var link_library “* xxx.db” 把目标库放入内存
工作库指定命令
- define_design_lib ADD –path ./xxx
dc 优化选项
- Pipeline
可以让工具在优化的时候根据需要插入流水线1
set optimize registers true -design Pipeline
可以看到被加的流水线都是以 Sx 结尾命名的
流水线出来的结果如果要往外送的话 要用寄存器寄存一下再送出去
DC TCL 约束相关
create_clock
获取端口 Clk 并设成周期为 2ns 的时钟 []内的不是必需的 -waveform 选项第一个参数表示在第 x ns时钟上升
在第 y ns 时钟下降以此来确定占空比 占空比默认 50%
create_clock [-name xxx] -period 2 [-waveform {x y}] [get_ports Clk]
group_path
给路径分组
由于综合工具如果发现同一组路径中最差的路径没办法优化到 meet 的话就会放弃优化提前退出综合以便不做无用功
由上图可以看出最差的路径在 COMBO 中已经超过了 Constraint Goal 所以当综合到 COMBO 的最差路径时综合就会结束
有时候我们不想综合提前结束 可以把路径分组这样其它组路径的 Critical Path 也会得到综合器的优化
|
|
- 比较有意思的一个参数:critical_range
这个参数可以指定一个范围 默认值是 0
即最差路径到(最差路径-critical_range)之间的路径都能得到优化最差的路径也能得到优化看下图:
这个 range 不是越大越好 如果太大了就会超过 Constraint Goal
使得原本已经 meet 了的路径也继续优化这样会极大的增加综合器的用时
一般不要超过时钟周期的 10% - weight
设置权重 默认值为 1 权重越高工具就会越集中力量优化该 group_path
set_max_area
|
|
上面的例子给 PRGRM_CNT_TOP 的设计施加了一个最大面积 100 单位的约束。
100 的具体单位是由 Foundry 规定的,定义这个单位有三种可能的标准:
- 一种是将一个二输入与非门的大小作为单位 1;
- 第二种是以晶体管的数目规定单位;
- 第三种则是根据实际的面积(平方微米等等)。
获取面积单位
先综合一个二输入与非门,用 report_area 看他的面积是多少,
- 如果是 1,则是按照第一种标准定义的;
- 如果是 4,则是第二种标准;
- 如果是其他的值,则为第三种标准
.synopsys_dc.setup
dc 启动时会自动执行这个文件, 里面一般做一些变量的设置工作
这个文件可以在三个地方存在1.
-
DC 安装目录下如: SYN2021.06-SP5/admin/setup/.synopsys_dc.setup
-
Home 目录下: ~/.synopsys_dc.setup
-
在具体项目根目录下
优先级是 3 > 2 > 1
set 和 set_app_var
set_app_var
专门用于设置DC 内部变量, 如果设置的变量不是DC 的内部变量, 则在运行的时候就会报错, 所以用set_app_var 来设置DC 的内部变量, 可以有效的防止手误导致设置错变量
set
C shell 中用于设置环境变量, 在dc 中可以设置任何变量, set_app_var 能设置的 set 也能设置, 但是不推荐用set 替代 set_app_var
工艺厂商提供的库文件的格式
一般有两种, 一种是.lib 一种是 .db
其中.lib 是给人看的, .db 是给DC 读的
lib to db
可以通过 library_compile 工具来转换
顶层相关操作
列出当前顶层状态
|
|
设置顶层
|
|
ddc 格式
里面至少含有网表( .v )信息和约束( .sdc ) 信息
查看ddc 文件可以使用 design_vision
check_design
在综合前应该用check_design 检查一下设计有没有明显缺陷
|
|
list_design
可以列出当前设计的所有模块, 其中顶层模块后面会跟 (*)
Save the ddc design before compile
在check_design 后把DC 内存里面的内容保存为 .ddc 文件, 这样如果设计文件没有改动的话, 下次可以直接读取该ddc 文件来替代前面的4 步
Save the ddc design after compile
综合之后保留ddc 是给后端使用的
保存的网表文件.v 是用来做后仿或者交给别的布局布线工具使用如innovers
set_load
加负载 ( 一般来说是加容性负载即加电容 ), 单位一般是pF
get* 命令
help get* 可以查看所有以get 开头的命令
set* 命令
help set* 可以查看所有以set 开头的命令
all* 命令
all_inputs
Returns a collection of input or inout ports in the current design
如: all_inputs C*
返回所以以C 开头的输入端口
all_outputs
Returns a collection of output or inout ports in the current design.
all_clocks
Returns a collection of all clocks in the current design
all_registers
Returns a collection of sequential cells or pins in the current design.
remove* 命令
help remove* 可以查看所有以remove 开头的命令
add* 命令
help add* 可以查看所有以add 开头的命令
filter 命令
DC 访问环境变量
env
|
|
get_unix_variables
|
|
getenv
|
|
setenv
设置环境变量
|
|
时序约束
时序分析
起点
- Inpurt port
- Clock pin of Flip-Flop or register
终点
- Output port
- Any input pin of sequential device, expect clock pin
时钟约束
|
|
约束时钟周期为2ns 即时钟频率为 500Mhz 占空比为50%
clock_uncertainty
|
|
clock_latency
clock_transition
模拟时钟的斜坡
Pre/Post Layout Clock
时钟树综合之后就不需要使用 set_clock_latency -max 2 MCLK 了, 因为这时候寄存器的位置已经确定, 可以使用 set_propagated_clock MCLK 来让DC 自己去提取延时信息
set_input_delay
通过设置输入的延时, 来间接的告诉DC Tmax 最大是多少, 从而达到约束Tmax 的目的
set_output_delay
通过设置输出的延时, 来间接的告诉DC Tmax 最大是多少, 从而达到约束Tmax 的目的
Input delay multiple input path (-add_delay)
-clock_fall 意思是相对于时钟的下降沿延时0.3ns
-add_delay 意思是对同一条路径, 允许有两个约束, 让DC 自己选一个相对紧的约束, 如果
不加 -add_delay 的话, DC 会默认使用后面的约束覆盖掉前面的约束
set_ideal_network
如时钟复位这种超高扇出的网络如果不设成ideal network 的话, DC 综合的时候就会插入一些BUFFER 来增加它的驱动能力, 但是往往时钟和复位这些都是在后端CTS ( CLOCK TREE SYNTHESIZE ) 做的
如上图所示, 理想网络经过逻辑门之后如果有一个输入信号不是理想网络的话, 那么输出就不是理想网络
set_ideal_network 一般的设置对象是 ports 或者 pins, 如果要对nets 设置必须加上 -no_propagate 选项, 意思是说驱动该net 的信号是理想网络, 并不是真正的把net 设置成理想网络, 针对net 设置的话有专门的命令 set_ideal_net
Model ideal network Delay and Transition
set_ideal_xxx 可以设置一般的网络, 不像 set_clock_xxx 只能针对时钟网络
输入输出约束
Multiple inputs/outputs - same constraints
set_input_delay 对除CLK 外所有的input 路径做约束, 其中 -clock CLK 是指以CLK 为参考点
set_output_delay 对所有的outputs 路径做约束, 其中 -clock CLK 是指以CLK 为参考点
Different Port Constraint, remove_input_delay
如果是不小心设了 CLK 的input delay, 可以使用 remove_input_delay [get_port CLK] 来移除对时钟的input delay 约束
组合逻辑约束
通过设置B 的input_delay 以及D 的output_delay, 从而间接的约束了组合逻辑F
Time budget example ( 时间预算示例 )
对于KOBE’S DESIGN output_delay 设为6ns 那么CLK-> M 这条路径就有4ns
对于MY_DESIGN input_delay 设为6ns 那么N 这条路径就有4ns
合起来看 CLK->M + N => 8ns 还有2ns 的余量来给setup time hold time 这些
一般来说约束40% 即可
分组约束 (group_path)
Create user-defined path groups
分组的好处是, 每一组的最坏的路径都能得到优化
Enable Near-critical path optimization
使能优化在最差路径的0.2ns 范围内的所有路径
-critical_range 最好不要超过时钟周期的 10%, 这是Synopsys 官方文档建议的
Prioritizing path groups: -weight
权重最大是5, 默认值是1, 权重越大, DC 就会花更多精力去优势那个组
Multiple clock input delay
其中CLKA 是虚拟时钟, DC 会使用CLKA 和 CLKC 的上升沿之间的最小距离作为参考计算
如上图所示两个时钟的上升沿最小距离是1ns, TN = 1 - 0.55 - Tsetup
Mutiple clock output delay
其中CLKD 和 CLKE 都是虚拟时钟, 这里使用 -add_delay 可以使用两条约束对同一个输出端口OUT1 进行约束, DC 会各自计算并使用最紧的约束
相对于CLKD 的约束, Ts = 0.67 - 0.16 = 0.52ns
相对于CLKE 的约束, Ts = 1 - 0.52 = 0.48ns
Inter clock uncertainty
设置多时钟的uncertainty 一定要指定是哪两个时钟, 如上图所示, 使用 -from clk_xxx to clk_yyy
Generated clocks - instantiated register
使用 create_generated_clock -divide_by 2 约束设计中的二分频电路,
其中 [get_pins FF1/Q ] 里面的FF1/Q 是对应的分频后的时钟的输出, 这个东西直接在RTL 中是看不出来的, 因为要具体到寄存器的端口, 这个可以在综合前通过 write -format verilog -hier -output unmapped/xxx.v
保存的unmaped 下的GTECH 文件中找到, 因为DC 把RTL 代码读入内存时会把它转换成Synopsys 的中间格式 GTECH 格式, 这种格式可以看到寄存器端口
set_false_path or set_clock_groups
其中真实的路径只有两条, 即紫色的CLK1 -> CLK1
和蓝色的 CLK2 -> CLK2, 如果不加约束的话, DC 会认为有四条路径( CLK2 -> CLK1, CLK1 -> CLK2 )
使用 set_false_path 或者 set_clock_groups -logically_exclusive -group CLK1 -group CLK2 即可解决
Logically exclusive clocks
如上图左侧所示, CLK1 和 CLK2 的内部数据有交互, 因此单纯的set_false_path 会让DC 直接忽略掉CLK1 和 CLK2 的交互部分, 事实上我们仅仅需要把经过out 端口的路径设成false_path 即可, 如上图红色部分所示仅仅约束通过 out 端口的CLK 路径即可
Multiple clocks per register
如上图所示, 如果不加约束的话, DC 会认为有4 种可能:
- CLK1 产生数据 CLK1 去采样
- CLK1 产生数据 CLK2 去采样
- CLK2 产生数据 CLK1 去采样
- CLK2 产生数据 CLK2 去采样
实际上应该是只有两种情况: sel 为0 时使用CLK1, sel 为1 时使用CLK2
Asynchronous design constraints
|
|
Multi-cycle Design (set_multicycle_path)
这种多周期路径, 在RTL 设计的时候就要加入移位寄存器来做使能信号, 只有当C 的En 为高的时候才把结果锁存到Y
-setup 6 的意思是允许6 个时钟周期之后再去采样
DC 默认会在 MH = 0 处检查HOLD Time ( 这样的话DC 会在中间插入一些复杂的结构 ), 实际上不需要这样, 只需要在采样数据的时候检查HOLD Time 就可以了, 通过设置hold time 的检查位置在MH=Msu-1, 即setup 设置的时钟周期 - 1, 如使用 -hold 5 的意思是在默认检查HOLD Time 的位置往前移5 个时钟周期, 即在MH=5 处检查 HOLD Time
上图所示约束了 Two-cycle path 那条蓝色的路径为多周期路径, 多周期为2
change_name
|
|
DC 完成了ASIC 设计流程中的RTL to NETLIST 过程, 后续需要有第三方工具完成netlist to GDS 的实现,
而第三方工具对于netlist 有字符语法上的限制, 所以需要使用 change_names 命令, 才能让第三方工具正确识别netlist
Model output capacitive load
set_input_transition
打散层次化 (ungroup -flatten -all)
|
|
流水线及寄存器优化
Solution: pipeline or register retiming 优化流水线或者寄存器
compile_ultra -retime 是针对普通寄存器的优化, 并不针对流水线, 它主要是均衡寄存器前面的负载, 有可能会把寄存器前的一部分组合逻辑放到寄存器后, 或者反过来
set_optimize_registers_true 之后, 在compile_ultra 的时候, DC 就会对流水线的寄存器进行调整优化
如上图所示, 比如前一级寄存器处的延时比较大, DC 可能就会把前一级的一部分东西摞到后一级去, 以此来减小关键路径的延时
最终会把每一级流水线的延时都调整成差不多
Adaptive and register retiming flow
set_optimize_registers 后面可以根实例名表示只对某一个实例的流水线优化
-scan 的意思是会生成扫描链用的寄存器
-retime DC 会优化普通寄存器
Resulting pipeline
Maintaing registered outputs 指定不被优化的寄存器
指定不优化P3 寄存器, 因为这个是用来锁存输出的寄存器, 我们不希望被 -retime 选项优化, 从而导致输出引入组合逻辑
Multi-core optimization 设置多核跑综合
|
|
貌似需要License 支持
时序报告
report_timing
会报告时序违例, PVT ( power voltage temperature ) , 线负载模型等等
用法
-nets 用来报告连线上的负载个数
-significant_digits_number 这个选项用来指定报告中的小数点位数, 最高貌似是13 位小数
示例
-
report_timing Demo1
图中f/r 代表 falling ( 下降延时 ) / rising ( 上升延时 ), 因为DC 计算延时时会计算两次,
report_timing 的时候只使用延时较大的结果, 如果显示r 说明上升延时比较大
查看工艺库的器件延时信息可以用 report_libs 命令
-
report_timing Demo2
-
report_timing Demo3
- report_timing
只报告一条最坏的路径, 即Slack = -0.3 - report_timing -max_paths 2
报告两个不同端点的最坏的两条路径, 即Slack = -0.3 和 Slack = -0.15 - report_timing -nworst 2 -max_paths 2
报告最坏的两条路径( 允许同一结束端点 ) 即 Slack = -0.3 和 Slack = -0.25
- report_timing
-
report_timing -loops
可以检查设计中是否有产生 latch, 如果有就要解决掉
report_constraint
-all_violations
报告所有时序违例
Edge sensitive in path delays
DC 在计算延时信息时会计算两次, 比如经过一个反向器, 充电和放电时间是不一样的,
即经过上升的时间延时和经过下降沿的时间延时是不一样的, 体现在report_timing 时的
r/f 如果上升延时比较大就显示 r, 如果下降延时比较大就显示 f
Effect of driving cell on input delay
set_driving_cell 即模仿外部驱动, 添加之后会使驱动信号有斜坡,
即在set_input_delay 的基础上增加了延时, 这样的建模会更加贴近实际电路
设置set_driving_cell 一定要基于0 负载来设置
Always check for invalid exceptions (report_timing_requirements -ignored)
这条命令会报告出所有的时钟异常约束( 如set_false_path, set_clock_groups, set_multicycle_path 等约束 ), 方便用户检查设置得对不对
set_isolate_ports
|
|
在所有的输出口上插入 buffer 用来和外部电路隔离
DC 输出工程文件
sdc
输出约束文件
|
|
SCAN-DEF 输出扫描链信息
输出扫描链文件
|
|
ddc 文件
|
|
消除 verilog assign statements
多端口直连导致 assign (set_fix_multiple_port_nets)
设计代码不规范会导致DC 综合后的网表文件或者 .sdf 文件里出现assign 语句或者tri 声明, 这是不允许的
如上图所示的设计综合后就出现了assign 语句, 解决办法如下
使用
|
|
意思是通过插入buffer 来修多端口直连的问题
tri 声明导致 assign (set_app_var verilogout_no_tri true)
通过设置 verilogout_no_tri 为true 即可解决
|
|
设置完之后再综合, DC 就会把tri 变成wire
change_names
DC 的输出文件中经常会有反斜杠\, 这在dc 中是没有问题的, 但在很多第三方工具上就会出问题, 为了兼容第三方工具, 需要在综合之后保存网表之前使用change_names 来解决
如上图所示, 使用 change_names -rules verilog -hier
把输出文件中的信号以verilog 的标准来命名
输出命令总结
|
|
write_sdc 和 write_sdf 命令都有 -version 版本信息, 可以通过 man 命令查看这两条命令的版本信息
DC 输出报告
|
|
Tcl 编程
if else
|
|
switch
|
|
while
|
|
for
|
|
foreach
|
|
Create file and write info to it
|
|
Read from a file
|
|
proc
|
|
先source 一下tcl 文件, 把max 函数读入内存, 之后可以直接在终端 max 1 2 调用
|
|
Creat a link to the variable outside
|
|
相当于创建一个指针指向外部的变量