LAB14_1 时钟树综合

这个章节的主要学习目标如下:

1)时钟树综合前的准备工作熟悉

2)时钟树综合的跑法

3)时钟树结果分析

4)时钟树综合后的时序优化(PostCTS的timing优化)

首先,我们按照lab的要求来打开pr.inv这个数据。

我们可以直接用我们打开数据的命令:

restoreDesign ../saved/pr.inv.dat DTMF_CHIP

打开数据后,我们要读入做时钟树综合前的一些设置,比如这个lab中的dtmf.ccopt。这个文件的内容如下(用gvim dtmf.ccopt即可打开该文件):

1
2
set_ccopt_property buffer_cells [ list CLKBUFX1 CLKBUFX12 CLKBUFX16 CLKBUFX2 CLKBUFX20 CLKBUFX3 CLKBUFX4 CLKBUFX8 CLKBUFXL ]
set_ccopt_property inverter_cells [ list CLKINVX1 CLKINVX12 CLKINVX16 CLKINVX2 CLKINVX20 CLKINVX3 CLKINVX4 CLKINVX8 CLKINVXL ]

这两句其实就是设置工具长时钟树时可用的clock buffer和clock inverter cell list 。

很多新手肯定会有疑问,我是初学者,我哪里能知道做时钟树前要设置哪些设置,而且我压根不知道ccopt有哪些相关的property。

这里教大家一个大招,可以通过下面的命令来报告出所有ccopt相关的property。至于要设置哪些,这是慢慢积累的一个过程。刚开始只要知道设置一些常用的设置即可,等后续经验多了,自然就都会了。

CTS 中 Buffer 和 Inverter 的区别与使用场景

1. 基本概念

在 CTS(Clock Tree Synthesis,时钟树综合)阶段,工具会插入时钟 buffer 或时钟 inverter 来构建时钟树,从而满足时钟网络的驱动能力、时钟偏斜、时钟延迟和 transition 等要求。

常见脚本如下:

1
2
set_ccopt_property buffer_cells [ list CLKBUFX1 CLKBUFX2 CLKBUFX4 CLKBUFX8 ... ]
set_ccopt_property inverter_cells [ list CLKINVX1 CLKINVX2 CLKINVX4 CLKINVX8 ... ]

这两条命令的作用是告诉 Innovus/CCOpt:

  • buffer_cells:CTS 阶段允许使用哪些时钟缓冲器;
  • inverter_cells:CTS 阶段允许使用哪些时钟反相器。

2. Buffer 和 Inverter 的逻辑区别

2.1 Buffer

Buffer 不改变信号极性,逻辑功能为:

1
Y = A

也就是:

1
2
A = 0 → Y = 0
A = 1 → Y = 1

Buffer 的主要作用不是改变逻辑,而是增强驱动能力、改善 transition、分担扇出和控制时延。


2.2 Inverter

Inverter 会改变信号极性,逻辑功能为:

1
Y = ~A

也就是:

1
2
A = 0 → Y = 1
A = 1 → Y = 0

如果单独插入 inverter,会导致信号反相,因此在不能改变逻辑功能的路径上需要谨慎使用。


3. 工程中 Buffer 的常见用途

Buffer 通常用于不希望改变逻辑功能,只希望改善物理或时序特性的场景。

3.1 增强驱动能力

当一个信号需要驱动很多负载时,原始驱动单元可能无法满足 transition 或 fanout 要求,此时可以插入 buffer。

1
driver → buffer → many loads

作用:

  • 降低前级负载;
  • 改善 transition;
  • 减少 slew violation;
  • 提高信号传播质量。

3.2 修复 Hold 违例

Hold 违例通常是数据路径太短,数据到达下一级寄存器太快。此时可以在数据路径上插入 buffer 增加延迟。

1
Reg1/Q → buffer → Reg2/D

作用:

  • 增加 data path delay;
  • 修复 hold violation。

3.3 长线中继

如果一根连线较长,RC 寄生较大,直接驱动会导致延迟和 transition 变差,可以在中间插入 buffer 作为中继。

1
driver → long wire → buffer → long wire → load

3.4 CTS 时钟树构建

在 CTS 中,clock buffer 是最常用的时钟树单元,用于构建多级时钟网络。

1
clock source → CLKBUF → CLKBUF → register clock pin

作用:

  • 增强时钟驱动能力;
  • 控制 clock transition;
  • 平衡 clock skew;
  • 控制 clock latency;
  • 驱动大量寄存器 clock pin。

4. 工程中 Inverter 的常见用途

4.1 实现逻辑取反

Inverter 最直接的作用是实现信号反相,例如:

1
reset_n → inverter → reset

或者:

1
enable → inverter → disable

4.2 两个 Inverter 串联等价于 Buffer

两个 inverter 串联后,最终逻辑极性不变:

1
A → INV → INV → Y

因为:

1
Y = ~~A = A

因此在工程中,有时会使用 inverter pair 来实现类似 buffer 的作用。

使用 inverter pair 的原因可能包括:

  • inverter 面积更小;
  • inverter 延迟更合适;
  • inverter 驱动档位更多;
  • 工具优化选择更灵活;
  • rise/fall transition 更容易调整。

4.3 CTS 中参与时钟树优化

在 CTS 阶段,clock inverter 也可以参与时钟树构建。工具可以追踪时钟极性,因此中间节点允许出现反相时钟,只要最终到达寄存器 clock pin 的时钟极性满足要求即可。

常见情况是成对使用 inverter:

1
clk → CLKINV → CLKINV → clk

这样最终时钟极性不变,但工具可以利用 inverter 的延迟、驱动和边沿特性优化时钟树。


5. CTS 中什么时候用 Buffer,什么时候用 Inverter?

在实际 CTS 中,通常不是工程师手动决定每一级使用 buffer 还是 inverter,而是由 CCOpt/CTS 工具根据目标自动选择。

工具会综合考虑:

  • clock skew;
  • clock latency;
  • clock transition;
  • fanout;
  • insertion delay;
  • 功耗;
  • 面积;
  • 布线拥塞;
  • 时钟极性。

5.1 优先使用 Clock Buffer 的场景

Clock buffer 不改变时钟极性,因此是 CTS 中最直接、最安全的选择。

适合场景:

  • 保持时钟极性;
  • 增强时钟驱动能力;
  • 驱动大扇出寄存器;
  • 切分长时钟线;
  • 改善 clock transition;
  • 平衡不同分支 latency;
  • 控制 clock skew。

示意:

1
2
3
4
5
6
7
clk_root

CLKBUF

CLKBUF CLKBUF CLKBUF
↓ ↓ ↓
regs regs regs

5.2 使用 Clock Inverter 的场景

Clock inverter 会改变时钟极性,因此不能随意单独使用。但在 CTS 中,工具可以合理使用 inverter 来优化时钟树。

常见场景包括:

1)两个 inverter 成对使用

1
clk → CLKINV → CLKINV → clk

最终极性不变,相当于 buffer,但可能在延迟、面积、功耗或 transition 上更有优势。

2)调整 rise/fall transition

Inverter 会交换上升沿和下降沿的传播特性,因此工具有时会使用 inverter 来优化时钟边沿质量。

3)中间节点允许反相

CTS 工具能够追踪 clock polarity,因此时钟树中间节点可以是反相的,只要最终到达 sink 的时钟极性正确即可。

4)特殊时钟相位需求

某些特殊单元、latch 或 clock gating 结构可能需要特定极性的时钟,此时可以通过 inverter 生成反相时钟。


6. Buffer 和 Inverter 的工程区别总结

对比项 Buffer Inverter
逻辑功能 不改变极性 改变极性
表达式 Y = A Y = ~A
是否影响功能 一般不影响 单独使用会影响
常见用途 增强驱动、修 transition、修 hold、长线中继 逻辑取反、极性调整、成对作为 buffer
CTS 中使用 最常用,直接构建时钟树 可使用,但要注意极性
ECO 修 hold 常用 通常需要成对使用
工具优化 稳定直接 更灵活,但需管理极性

7. 手动 ECO 时的注意事项

在手动 ECO 中,如果只是想增加延迟或者增强驱动,通常优先插入 buffer:

1
Reg1/Q → BUFX1 → Reg2/D

如果使用 inverter,则需要成对插入,避免改变逻辑功能:

1
Reg1/Q → INV → INV → Reg2/D

否则单独插入一个 inverter 会导致逻辑反相,可能造成功能错误。


8. 一句话总结

Buffer 是不改变极性的时钟/信号中继单元,主要用于增强驱动、改善 transition、修复 hold 和构建时钟树;Inverter 会改变极性,主要用于逻辑取反,也可以在 CTS 中成对使用来辅助优化时钟树。CTS 阶段具体使用 buffer 还是 inverter,通常由工具根据 skew、latency、transition、功耗和面积自动决定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
innovus 5> innovus 5> set_ccopt_property *  -help
Usage: set_ccopt_property * <value>:
add_driver_cell add_exclusion_drivers add_port_driver
additional_buffer_depth additional_buffer_depth_skew_group_fraction adjacent_rows_legal
adjust_sink_grid_for_aspect_ratio allow_non_standard_inputs_clock_gate annotated_delay_to
annotated_transition associated_row auto_limit_insertion_delay_factor
auto_limit_insertion_delay_factor_skew_group auto_limit_insertion_delay_max_increment
auto_limit_insertion_delay_max_increment_skew_group balance_mode bounds
buffer_cells cannot_clone_reason cannot_fix_pre_route
cannot_merge_reason capacitance_override case_analysis
ccopt_auto_limit_insertion_delay ccopt_merge_clock_gates ccopt_merge_clock_logic
ccopt_worst_chain_report_timing_too cell_density cell_halo_mode
cell_halo_rows cell_halo_sites cell_halo_x
cell_halo_y center_line check_route_follows_guide
check_route_follows_guide_min_length clock_gate_buffering_location clock_gate_movement_limit
clock_gating_cells clock_gating_depth clock_gating_depth_top_down
clock_gating_only_optimize_above_flops clock_period clock_source_cells
clock_tree clock_tree_generator_sink_is_leaf clock_tree_source_group
clock_trees clone_clock_gates clone_clock_logic
compatibility_warning consider_during_latency_update consider_power_management
constrains def_lock_clock_sinks_after_routing delay_cells
detailed_cell_warnings effective_clock_halo_x effective_clock_halo_x_source
effective_clock_halo_y effective_clock_halo_y_source effective_clock_period
effective_clock_period_sources effective_sink_type enable_all_views_for_io_latency_update
enable_nanoroute_layer_check_failure error_on_problematic_slew_violating_nets
error_on_problematic_slew_violating_nets_max_printout exclusive_sinks_rank
exit_if_stage_delay_sigma_target_over_constrained extract_balance_multi_source_clocks extract_clock_generator_skew_group_name_prefix
extract_clock_generator_skew_groups extract_clock_group_skew_group_name_prefix extract_cts_case_analysis
extract_network_latency extract_no_exclude_pins extract_pin_insertion_delays
extract_skew_group_sinks_at_clock_node_timing_endpoints extract_source_latency
extract_through_multi_output_cells_with_single_clock_output extracted_from_clock_name extracted_from_constraint_mode_name
extracted_from_delay_corners filter_cell_lists_for_frequency_dependent_max_cap_constraints
final_cell flexible_htree flexible_htree_placement_legalization_effort
force_clock_objects_to_propagated force_clock_tree force_update_io_latency
frequency_dependent_max_cap_usability_check_max_cap_fanout_factor generated_by_sinks hard
htree_sinks hv_balance ideal_net
ignore_pins ignore_problematic_skew_as_result_of_dont_touch_nets
image_directory implicit_sink_type include_source_latency
insertion_delay inst_name_prefix inverter_cells
inverting is_genus_clock_gate is_sdc_clock_root
is_vertical isolated layer_density
leaf_buffer_cells leaf_inverter_cells legalized_on_clock_spine
library_trace_through_to lock_on_clock_spine log_precision
log_special_case_cell_selections logic_cells long_path_removal_cutoff_id
long_path_removal_percentile manage_power_management_illegalities max_buffer_depth
max_cell_height max_clock_cell_count max_driver_distance
max_fanout max_root_distance max_source_to_sink_net_length
max_source_to_sink_net_resistance maximum_insertion_delay merge_clock_gates
merge_clock_logic mixed_fanout_net_type mode
move_clock_gates move_logic move_middle_cell_first_when_adding_wire_delay
net_name_prefix net_type net_unbufferable
node_type omit_symmetry opt_ignore
original_names override_minimum_max_trans_target override_minimum_skew_target
override_vias override_zero_placeable_area parents
partition_boundary_inverting partition_groups pin
pin_route_type pin_target_max_trans place_driver_in_center_of_fanout
post_conditioning post_conditioning_enable_drv_fixing
post_conditioning_enable_drv_fixing_by_rebuffering post_conditioning_enable_routing_eco
post_conditioning_enable_skew_fixing_by_rebuffering power_weight primary_delay_corner
primary_reporting_skew_groups primary_reporting_skew_groups_log_min_max_sinks
pro_enable_drv_fixing_by_rebuffering recluster_ignore_pins remove_bufferlike_clock_logic
rename_clock_tree_nets report_only_skew_group_with_target
report_only_timing_corners_associated_with_skew_groups route_balancing_buffers_with_default_rule route_type
route_type_autotrim routing_override routing_preferred_layer_effort
routing_top_fanout_count routing_top_min_fanout routing_top_transitive_fanout
schedule sink_grid sink_grid_box
sink_grid_exclusion_zones sink_grid_sink_area sink_instance_prefix
sink_type sink_type_reasons sinks
sinks_active size_clock_gates size_clock_source
size_logic skew_band_size skew_group_report_columns
skew_group_report_histogram_bin_size skew_groups_active skew_groups_active_sink
skew_groups_constraining skew_groups_constraining_sink skew_groups_ignore
skew_groups_sink skew_groups_source_pin skew_passes
skew_passes_ideal_mode skew_passes_per_cluster source_driver
source_group_clock_trees source_input_max_trans source_latency
source_max_capacitance source_output_max_trans source_pin
sources spec_config_create_reporting_only_skew_groups stack_via_rule
stack_via_rule_required stop_at_sdc_clock_roots target_insertion_delay
target_insertion_delay_wire target_max_capacitance target_max_stage_delay_sigma
target_max_trans target_max_trans_sdc
target_multi_corner_allowed_insertion_delay_increase target_skew target_skew_wire
timing_connectivity_based_skew_groups timing_connectivity_based_skew_groups_balance_master_clocks
timing_connectivity_info top_buffer_cells top_inverter_cells
trace_bidi_as_input trace_through_to transitive_fanout
trunk_cell trunk_override update_io_latency
use_estimated_routes_during_final_implementation use_inverters use_macro_model_pin_cap_only
use_receiver_model_capacitance_for_drv useful_skew_clock_gate_movement_limit useful_skew_implementation_cache_hold_slacks
useful_skew_max_delta useful_skew_min_delta useful_skew_post_implement_db

设置好ccopt相关的设置后,我们需要基于sdc和这些ccopt property来产生clock tree spec文件。因为工具长tree会根据这个spec文件来做tree。

create_ccopt_clock_tree_spec

spec产生后,我们就可以使用下面的命令来跑时钟树综合和时钟树综合后的时序优化。

Innovus CTS 中 create_ccopt_clock_tree_spec 和 Spec 的作用

1. spec 是什么?

spec 是英文单词 specification 的缩写,中文通常翻译为:

  • 规格
  • 规范
  • 说明
  • 约束说明
  • 配置说明文件

在 EDA 流程中,spec 通常指工具执行某个任务时需要遵守的规则或配置说明。

常见例子:

英文 中文含义
design spec 设计规格
timing spec 时序规格
interface spec 接口规格
clock tree spec 时钟树规格文件

2. Clock Tree Spec 是什么?

在 CTS(Clock Tree Synthesis,时钟树综合)阶段,clock tree spec 可以理解为:

时钟树综合的规则说明文件,也可以理解为 CTS 的“施工图”。

它告诉工具应该如何搭建时钟树。

Clock tree spec 中通常会包含:

  • 设计中有哪些 clock;
  • clock root 在哪里;
  • clock sink 有哪些;
  • CTS 可以使用哪些 clock buffer;
  • CTS 可以使用哪些 clock inverter;
  • 目标 clock skew 是多少;
  • 目标 clock transition 是多少;
  • 目标 clock latency 是多少;
  • 是否存在 clock gating;
  • 是否有特殊 clock 处理规则。

3. 为什么需要 Clock Tree Spec?

CTS 工具不能随便插入 buffer 或 inverter,它需要知道建树规则。

例如,工具需要知道:

1
2
3
4
5
6
7
哪些时钟需要建树?
时钟源在哪里?
终点寄存器有哪些?
目标 skew 要控制到多少?
transition 要控制到多少?
允许使用哪些 clock cell?
有没有 generated clock 或 clock gating?

因此,在真正跑 CTS 之前,需要先根据 SDC 约束和 CCOpt 设置生成 clock tree spec。

可以这样理解:

1
2
3
4
5
6
7
8
9
SDC 时序约束
+
CCOpt property 设置

create_ccopt_clock_tree_spec

Clock Tree Spec

CTS 根据 Spec 搭建时钟树

4. create_ccopt_clock_tree_spec 是什么?

命令如下:

1
create_ccopt_clock_tree_spec

可以拆开理解:

1
2
3
4
create       创建
ccopt Cadence Clock Optimization
clock tree 时钟树
spec 规格 / 规范文件

所以它的作用是:

根据当前设计中的 SDC 约束和 CCOpt 属性设置,生成 CCOpt/CTS 使用的 clock tree spec 文件。


5. SDC 和 CCOpt Property 分别提供什么?

5.1 SDC 提供时序约束

SDC 文件中通常包含:

1
2
3
4
5
create_clock -name clk -period 1.0 [get_ports clk]
set_clock_uncertainty ...
set_input_delay ...
set_output_delay ...
set_false_path ...

SDC 主要告诉工具:

  • 设计中有哪些时钟;
  • 时钟周期是多少;
  • 输入输出延迟是多少;
  • 哪些路径是假路径;
  • 时序分析应该按照什么约束进行。

5.2 CCOpt Property 提供建树规则

CCOpt property 用来告诉工具 CTS 应该怎么做。

常见设置包括:

1
2
3
4
set_ccopt_property buffer_cells [...]
set_ccopt_property inverter_cells [...]
set_ccopt_property target_skew ...
set_ccopt_property target_max_trans ...

它们主要告诉工具:

  • CTS 可以使用哪些 clock buffer;
  • CTS 可以使用哪些 clock inverter;
  • 目标 skew 是多少;
  • 目标 transition 是多少;
  • 时钟树优化目标是什么。

6. 生成 Spec 后做什么?

生成 clock tree spec 后,就可以开始跑时钟树综合。

常见命令类似:

1
2
create_ccopt_clock_tree_spec
ccopt_design

或者有些流程会分开写:

1
2
ccopt_design -cts
ccopt_design -postcts

具体命令会根据 Innovus 版本和脚本流程有所不同。


7. CTS 做了什么?

CTS 会根据 clock tree spec 插入 clock buffer 和 clock inverter,建立真实的时钟树。

在 Place 阶段,时钟通常还是:

1
ideal clock

CTS 之后,时钟变成:

1
propagated clock

也就是说,工具开始考虑真实的:

  • clock latency;
  • clock skew;
  • clock transition;
  • clock insertion delay。

8. 为什么 CTS 后还要做时序优化?

时钟树建立之后,时钟到达不同寄存器的时间不再完全相同,因此原来的时序情况可能发生变化。

CTS 后可能出现:

  • setup 违例;
  • hold 违例;
  • clock gating check 违例;
  • transition 违例;
  • skew 不满足要求。

所以 CTS 后通常还需要进行 post-CTS optimization,用来修复时序问题。

常见优化包括:

  • 修复 setup;
  • 修复 hold;
  • 调整 clock buffer;
  • 优化 clock gating 路径;
  • 改善 transition;
  • 降低 clock skew。

9. 类比理解

可以把 CTS 类比成修建一条“时钟高速公路”。

1
2
3
4
SDC = 告诉工具时钟周期和时序要求
CCOpt property = 告诉工具可以用哪些材料、目标指标是多少
Clock Tree Spec = 时钟树施工图
CTS = 按照施工图真正搭建时钟树

10. 一句话总结

spec 是 specification 的缩写,表示“规格/规范”。在 CTS 中,clock tree spec 是时钟树综合的规则说明文件,create_ccopt_clock_tree_spec 会根据 SDC 和 CCOpt property 生成该文件,后续 CTS 工具会按照这个 spec 插入 clock buffer/inverter,搭建真实时钟树,并进行 CTS 后时序优化。

利用GUI图形界面分析时钟树质量 (CTD)

Clock—-Ccopt Clock Tree Debugger

点击OK后弹出如下结果。

这里要求大家熟悉下图中所框出来的三个地方。通过这个CTD还可以来trace设计的时钟结构。

图片当中的sink是啥意思:

这里的 sink 在 CTS / clock tree 里可以理解为:

时钟树的终点,也就是 clock 最终要送到的负载点。

在数字后端里,最常见的 sink 就是:

1
寄存器 / 触发器的 clock pin

比如:

1
clk root → clock buffer → clock buffer → DFF/CLK

这里最后的 DFF/CLK 就是一个 clock sink


1. sink 为啥叫 sink?

sink 英文原意有“汇入点、终点、接收端”的意思。

在时钟树里:

1
clock source / root  →  clock network  →  clock sinks

可以理解为:

1
时钟源头  →  时钟树传播  →  各个寄存器时钟端

所以:

名词 含义
clock source / root 时钟源头
clock tree 时钟分发网络
clock sink 时钟终点 / 时钟负载
sink pin 接收时钟的 pin,比如 DFF 的 CK

2. 图里“大部分 sink 落在 0.5–0.55ns”是什么意思?

你图里说:

1
大部分 sink 落在 0.5–0.55ns 这个区间

意思是:

大多数寄存器的 clock pin,从 clock root 到达该 pin 的 clock latency 大约是 0.5ns 到 0.55ns。

也就是:

1
2
3
4
clock root 出发
经过若干级 clock buffer / inverter
最终到达 DFF/CLK
花了约 0.5~0.55ns

这个时间就是 clock tree latency / insertion delay


3. 举个简单例子

假设有三个寄存器:

1
2
3
4
clk root
├── buf1 ── buf2 ── reg_A/CK
├── buf3 ── buf4 ── reg_B/CK
└── buf5 ── buf6 ── reg_C/CK

那么:

1
2
3
reg_A/CK 是一个 sink
reg_B/CK 是一个 sink
reg_C/CK 是一个 sink

如果工具报告:

1
2
3
reg_A/CK latency = 0.51ns
reg_B/CK latency = 0.53ns
reg_C/CK latency = 0.50ns

那就说明这些 sink 的时钟到达时间都集中在 0.5ns 左右。


4. sink 分布集中说明什么?

如果大部分 sink 的 latency 都集中在一个比较窄的范围,比如:

1
0.50ns ~ 0.55ns

通常说明时钟树比较均衡,clock 到达不同寄存器的时间差不大。

这个时间差就和 clock skew 有关。

简单说:

1
2
latency:clock 从 root 到某个 sink 的延迟
skew:不同 sink 之间 clock latency 的差值

例如:

1
2
sink1 latency = 0.50ns
sink2 latency = 0.55ns

那么这两个 sink 之间的 skew 大约就是:

1
0.55 - 0.50 = 0.05ns

5. 一句话总结

sink 就是时钟树的终点,通常是寄存器的 clock pin。图里说大部分 sink 落在 0.5–0.55ns,意思是大多数寄存器的时钟到达延迟集中在这个范围,说明 clock tree 的 latency 分布比较集中。

通过这个CTD分析的一个好处是我们可以在CTD窗口任意选择一颗cell,此时layout上会同步高亮显示出这颗cell。而且还能高亮当前sink点对应的clock path走向。

除了分析时钟树质量和时钟树结构外,我们还需要关心设计的时序Timing情况。

我们可以通过timeDesign来报告出当前设计的时序。

第一个就是报告postCTS阶段的timing,因为此时我们就是做完了CTS,所以此时我们应该带上PostCTS来报timing。

第二个命令又再加了一个 -hold选项,这个代表是我们想让工具报出当前阶段的hold time情况。

【思考题】 为何这个阶段要看hold time?

优化时序方法

如果工具自己做完时钟树综合和时序优化后的timing还有较大violation,我们还可以通过命令自带的时序优化命令来做时序的优化——optDesign -postCTS -setup (-hold 代表我们希望让工具优化hold time)

这里也可以直接使用innovus的GUI界面直接打印出相关的Timing信息

Post-CTS 阶段为什么要检查 Hold Time?

1. 背景

在 Innovus 后端流程中,完成 CTS(Clock Tree Synthesis,时钟树综合)之后,需要重新报告 timing。

常见命令包括:

1
2
report_timing -postCTS
report_timing -postCTS -hold

其中:

  • -postCTS:表示报告 CTS 之后的时序情况;
  • -hold:表示报告 hold timing,也就是保持时间检查。

2. CTS 前后的 Clock 状态区别

CTS 之前:Ideal Clock

在 Place 阶段,时钟树还没有真正建立,clock 通常是 ideal clock。

1
2
clock latency ≈ 0
clock skew ≈ 0

此时工具假设时钟几乎同时到达所有寄存器,因此 hold 分析不够真实,主要关注 setup。


CTS 之后:Propagated Clock

完成 CTS 后,工具已经插入 clock buffer / clock inverter,建立了真实时钟树。

此时 clock 变成 propagated clock,会产生真实的:

1
2
3
4
clock latency
clock skew
clock insertion delay
clock transition

不同寄存器的 clock pin 收到时钟的时间不再完全相同,因此需要重新检查 setup 和 hold。


3. 为什么 Post-CTS 要重点看 Hold?

Hold 检查关注的是:

数据不能太早到达下一级寄存器。

如果数据路径太短,或者 CTS 后 capture clock 比 launch clock 晚很多,就可能导致数据过早到达,从而产生 hold violation。

例如:

1
Reg1/Q → 很短组合逻辑 → Reg2/D

CTS 前可能认为两个寄存器同时收到时钟:

1
2
Reg1 clock latency ≈ 0
Reg2 clock latency ≈ 0

CTS 后可能变成:

1
2
Reg1 clock latency = 0.20 ns
Reg2 clock latency = 0.50 ns

此时 capture clock 比 launch clock 晚,短数据路径就可能出现 hold 违例。


4. 为什么 Place 阶段不重点看 Hold,而 CTS 后要看?

阶段 Clock 状态 主要关注 原因
Place 阶段 ideal clock setup 时钟树未建立,主要优化长数据路径
Post-CTS 阶段 propagated clock setup + hold 真实 clock latency 和 skew 已出现
Post-Route 阶段 propagated clock + 真实 RC setup + hold 时序更接近 signoff 结果

Place 阶段不重点看 hold,是因为 clock tree 还没有建立,hold 结果容易失真。

CTS 之后必须看 hold,是因为真实 clock skew 已经出现,短路径问题可能被暴露出来。


5. optDesign -postCTS -setup 的作用

1
optDesign -postCTS -setup

该命令用于 CTS 后的 setup 优化。

Setup 违例通常说明数据路径太慢,工具可能通过以下方式优化:

  • 换更大驱动能力的 cell;
  • 优化长组合逻辑路径;
  • 调整 buffer;
  • 改善 transition;
  • 局部移动 cell。

6. optDesign -postCTS -hold 的作用

1
optDesign -postCTS -hold

该命令用于 CTS 后的 hold 优化。

Hold 违例通常说明数据路径太快,常见修复方法是:

  • 插入 delay buffer;
  • 增加短路径延迟;
  • 调整 buffer / inverter;
  • 优化 clock skew;
  • 修复过短的数据路径。

简单理解:

1
2
setup 违例:数据来得太晚,需要让数据路径更快
hold 违例:数据来得太早,需要让数据路径慢一点

7. 思考题答案整理

CTS 之前,时钟树尚未真实建立,clock 仍为 ideal clock,工具无法准确获得不同寄存器之间的 clock latency 和 clock skew,因此 hold 分析参考意义有限。

完成 CTS 后,工具已经插入 clock buffer / inverter 并生成真实时钟树,clock 由 ideal clock 变为 propagated clock。此时不同 clock sink 的时钟到达时间产生差异,真实 clock skew 和 insertion delay 开始影响寄存器之间的时序关系。

Hold 检查对 clock skew 和最小数据路径延迟非常敏感。CTS 后,一些在 ideal clock 下不明显的短路径问题可能暴露出来,因此 postCTS 阶段需要报告 hold timing,检查是否存在数据过早到达导致的 hold violation。若存在 hold 违例,可以使用 optDesign -postCTS -hold 进行优化,通过插入 buffer、增加短路径延迟等方式修复 hold 问题。


8. 一句话总结

CTS 后时钟树已经真实存在,clock latency 和 clock skew 会影响寄存器之间的数据保持时间,因此 postCTS 阶段必须开始检查并修复 hold violation。

可以使用下面的ECO直接对CTS之后的setup和hold违例进行修复

ECO配置的参数如下:

ESC 关闭 | 导航 | Enter 打开
输入关键词开始搜索