# Physical Design

> 物理设计全流程技能 - 从floorplan到GDSII，完整数字芯片物理设计指导

- Skill: `tangyangchao578-art/physical-design` (Agent Skill)
- Install (CLI): `npx skillmds@latest add tangyangchao578-art/physical-design`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tangyangchao578-art/physical-design/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tangyangchao578-art (https://skillmd.com/u/tangyangchao578-art)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tangyangchao578-art/physical-design

---


# 物理设计全流程技能

当用户需要进行数字芯片物理设计时，启用此技能。提供从 floorplan 到 GDSII 全流程指导，涵盖问题调试和优化。

## When to Activate

- 全芯片物理设计从头开始
- 模块级物理设计
- 时序收敛问题调试
- 物理设计流程优化
- 物理验证问题调试

---

## 行业经验数值

### 物理设计经验值

| 参数 | 28nm | 16nm | 7nm | 说明 |
|------|------|------|-----|------|
| Core 利用率 | 70-80% | 65-75% | 60-70% | 先进节点需更低 |
| 布线拥塞度 | < 85% | < 80% | < 75% | 超过需重新规划 |
| 标准单元密度 | < 85% | < 80% | < 75% | 局部密度 |
| 时钟树级数 | 3-5级 | 3-5级 | 4-6级 | 平衡 skew 和功耗 |
| 时钟 Skew | < 150ps | < 100ps | < 50ps | 同时钟域内 |

### 电源设计经验值

| 参数 | 典型值 | 说明 |
|------|--------|------|
| IR 降上限 | < 5% Vdd | 必须满足 |
| EM 电流密度 | < spec limit | 按工艺规则 |
| 电源环宽度 | 2-5um | 取决于电流 |
| 电源带间距 | 50-100um | 取决于 IR 要求 |

### DFM 经验值（先进节点）

| 参数 | 7nm | 5nm | 说明 |
|------|-----|-----|------|
| 金属密度范围 | 40-60% | 45-55% | CMP 要求 |
| 通孔冗余 | 单通孔禁止 | 双通孔 | 可靠性 |
| 线端扩展 | > 10nm | > 12nm | 制造余量 |

---

## 故障诊断框架

### 症状1：时序不收敛

**诊断步骤：**

```tcl
# 1. 检查时序报告
report_timing -max_paths 20 -slack_lesser_than 0

# 2. 分析拥塞
report_congestion -hotspot

# 3. 检查布局密度
report_design_density
```

**判断标准：**

| 症状 | 可能原因 | 诊断动作 |
|------|----------|----------|
| WNS 大且路径集中 | 关键路径问题 | 分析路径延迟组成 |
| TNS 大且分散 | 整体设计问题 | 检查利用率、拥塞 |
| 拥塞热点与时序违例重叠 | 布局问题 | 调整布局 |

**根本原因定位：**

| 根本原因 | 诊断特征 | 解决方案 |
|----------|----------|----------|
| 利用率过高 | > 80% | 增加面积或优化逻辑 |
| 拥塞严重 | > 85% | 重新规划布局 |
| 时钟 Skew 大 | > 150ps | 重做 CTS |
| Macro 摆放不合理 | 数据流绕远 | 重新摆放 Macro |

### 症状2：拥塞严重

**诊断步骤：**

```tcl
# 检查全局拥塞
report_congestion

# 检查局部拥塞热点
report_congestion -hotspot

# 检查布线资源
report_routing_resources
```

**判断标准：**

| 拥塞度 | 判断 | 行动 |
|--------|------|------|
| < 70% | 正常 | 继续 |
| 70-85% | 轻度 | 关注热点区域 |
| 85-95% | 严重 | 必须优化 |
| > 95% | 极严重 | 需重新规划 |

**根本原因定位：**

| 根本原因 | 诊断特征 | 解决方案 |
|----------|----------|----------|
| 标准单元密度过高 | 局部密度 > 85% | 分散摆放、增加通道 |
| Macro 太密集 | Macro 间距 < 50um | 重新摆放 Macro |
| 总线走线冲突 | 高位宽总线重叠 | 留专用通道 |
| 电源网格太密 | PDN 占用过多 | 优化 PDN 间距 |

### 症状3：IR 降过大

**诊断步骤：**

```tcl
# 运行 IR 降分析
run_ir_drop_analysis

# 检查 IR 热点
report_ir_drop -threshold 0.05

# 检查电源网格
report_power_grid
```

**判断标准：**

| IR 降 | 判断 | 行动 |
|-------|------|------|
| < 3% | 良好 | 继续 |
| 3-5% | 边缘 | 关注热点 |
| 5-7% | 严重 | 必须优化 |
| > 7% | 极严重 | 需重新设计 PDN |

**根本原因定位：**

| 根本原因 | 诊断特征 | 解决方案 |
|----------|----------|----------|
| 电源带宽不足 | 电源环电流密度高 | 加宽电源环 |
| 电源带间距过大 | 局部 IR 高 | 增加电源带 |
| 高功耗模块远离电源 | 模块处 IR 高 | 调整布局 |
| 电源通孔不足 | 过孔处电阻高 | 增加过孔 |

### 症状4：DRC 违规多

**诊断步骤：**

```tcl
# 运行 DRC
verify_drc

# 分类统计
report_drc -type {spacing width density}

# 定位热点
report_drc -hotspot
```

**分类处理：**

| 违规类型 | 占比高 | 处理优先级 |
|----------|--------|------------|
| 间距违规 | 拥塞导致 | 先解决拥塞 |
| 密度违规 | 填充问题 | 自动填充 |
| 天线违规 | 长线导致 | 跳线或二极管 |
| 过孔违规 | 布线问题 | 调整布线 |

---

## 优化迭代策略

### 迭代优化决策树

```
物理设计结果
    │
    ├── 时序不收敛？
    │       │
    │       ├── WNS > -500ps？
    │       │       ├── 是 → 局部优化（换驱动、有用偏斜）
    │       │       └── 否 → 继续
    │       │
    │       ├── WNS -500ps ~ -1ns？
    │       │       ├── 是 → 中等优化（重摆放、复制寄存器）
    │       │       └── 否 → 继续
    │       │
    │       ├── WNS < -1ns？
    │       │       ├── 逻辑级数 > 10？ → RTL 重构
    │       │       ├── 拥塞 > 80%？ → 重新规划布局
    │       │       └── 线延迟 > 50%？ → 重新摆放模块
    │       │
    │       └── 多工艺角问题？
    │               ├── SS 违例，FF OK → 建立时间优化
    │               └── FF 违例，SS OK → 保持时间优化
    │
    ├── 拥塞严重？
    │       │
    │       ├── 全局拥塞 70-80%？
    │       │       └── 轻度优化（增加 padding）
    │       │
    │       ├── 全局拥塞 80-90%？
    │       │       └── 中度优化（调整模块密度）
    │       │
    │       └── 全局拥塞 > 90%？
    │               ├── 增加面积 5-10%
    │               ├── 重新规划 Macro 位置
    │               └── 分解大模块
    │
    ├── IR 降过大？
    │       │
    │       ├── IR 降 3-5%？
    │       │       └── 增加电源带宽
    │       │
    │       └── IR 降 > 5%？
    │               ├── 重新设计 PDN
    │               ├── 增加电源带
    │               └── 高功耗模块重摆放
    │
    └── DRC 违规？
            │
            ├── 违规 < 100？
            │       └── 自动修复
            │
            ├── 违规 100-1000？
            │       └── 分类修复
            │
            └── 违规 > 1000？
                    └── 分析根本原因，可能需要重新布线
```

### 迭代次数预估

| 阶段 | 正常迭代次数 | 迭代内容 |
|------|--------------|----------|
| Floorplan | 2-3 次 | 面积、模块位置、电源网格 |
| Placement | 2-4 次 | 拥塞、时序、密度 |
| CTS | 1-2 次 | skew、latency |
| Routing | 1-2 次 | DRC、天线 |
| Timing Closure | 3-5 次 | 建立时间、保持时间 |

### 迭代收敛判断

**好的信号：**
- WNS 逐次改善
- TNS 逐次减少
- 拥塞度下降
- DRC 违规减少

**坏的信号：**
- WNS 来回震荡
- 优化一个违反引入新违反
- 拥塞热点转移
- 时序改善但功耗增加超预算

**迭代停止条件：**
- WNS ≥ 0（所有工艺角）
- DRC 零违反
- LVS 零违反
- IR 降 < 5%
- 连续 2 次迭代改善 < 5%

### 快速迭代技巧

**1. 分阶段验证**

```
Floorplan 后：验证 IR、模块位置
Placement 后：验证拥塞、初始时序
CTS 后：验证时钟 skew、latency
Routing 后：验证时序、DRC
Signoff 前：全量验证
```

**2. 增量优化**

```tcl
# 只优化问题区域，不做全局优化
place_opt -incremental
route_opt -incremental

# 只优化关键路径
opt_design -post_route -critical_path_only
```

**3. 热点修复**

```
1. 识别热点区域（拥塞、时序、IR）
2. 只修复热点，不影响其他区域
3. 验证修复效果
4. 检查是否引入新问题
```

### 迭代追踪表格

| 版本 | 日期 | WNS | TNS | 拥塞 | IR降 | DRC | 修改内容 |
|------|------|-----|-----|------|------|-----|----------|
| v1.0 | 01/01 | -800ps | -50ns | 85% | 4% | 500 | 初始 |
| v1.1 | 01/02 | -400ps | -20ns | 80% | 4% | 200 | 调整 Macro |
| v1.2 | 01/03 | -150ps | -5ns | 75% | 3% | 50 | 优化 Placement |
| v1.3 | 01/04 | +20ps | 0 | 72% | 3% | 0 | 时序优化 |
| v1.4 | 01/05 | +50ps | 0 | 70% | 2% | 0 | 最终签收 |

---

## 案例研究：时序收敛问题

### 背景
- 项目：某网络芯片
- 工艺：16nm FinFET
- 目标频率：800MHz
- 问题：SS 工艺角 WNS = -1.2ns，多次迭代无法收敛

### 问题现象
```
Timing Summary:
  WNS: -1.2ns (SS corner)
  TNS: -45ns
  NP: 128 paths

关键路径：packet_parser -> packet_buffer
逻辑级数：15级
```

### 诊断过程

**步骤1：分析拥塞**
```
全局拥塞：78%
局部拥塞热点：packet_parser 区域 95%
```
结论：拥塞严重，导致绕线延迟大

**步骤2：分析布局**
```
packet_parser 位置：(100, 100)
packet_buffer 位置：(900, 900)
距离：约 1.2mm
```
结论：模块距离过远

**步骤3：分析逻辑**
```
逻辑级数：15级（超过建议的 8-10 级）
```
结论：逻辑级数过多

### 解决方案

| 问题 | 解决方案 | 效果 |
|------|----------|------|
| 拥塞 95% | 增加 10% 面积 | 拥塞降至 80% |
| 距离 1.2mm | 移动 packet_buffer 靠近 parser | 距离降至 300um |
| 逻辑级数 15 | 插入流水级 | 逻辑级数降至 8 |

### 结果
```
Timing Summary:
  WNS: +50ps (SS corner)
  TNS: 0
  NP: 0
```
时序收敛，流片成功。

### 经验总结
1. 先解决拥塞问题，再处理时序
2. 数据流方向的模块应靠近放置
3. 逻辑级数 > 10 应考虑流水线

---

### 阶段 1：输入数据准备

**需要准备：**
- [ ] 综合后门级网表（.v）
- [ ] 时序约束（SDC）
- [ ] 工艺库文件（.lef, .lib, .tech, GDS）
- [ ] IO 摆放信息（.iof）
- [ ] 电源地规划
- [ ] Filling 规则

**检查：**
- [ ] 网表没有未连接端口
- [ ] 约束语法正确
- [ ] 库文件对应正确工艺版本

---

### 阶段 2.5：布局预估与规划

在正式布局前，进行布局预估可以减少迭代次数。

#### 面积预估方法

**1. 基于综合结果预估**

```
综合后面积 × 预估系数 = 物理设计面积

预估系数参考：
- 28nm: 1.3 - 1.5
- 16nm: 1.4 - 1.6
- 7nm: 1.5 - 1.8
```

**2. 基于模块预估**

| 模块类型 | 面积系数 | 说明 |
|----------|----------|------|
| 纯逻辑 | 1.2 - 1.4 | 标准单元为主 |
| SRAM 密集 | 1.1 - 1.2 | 存储器面积稳定 |
| 混合模块 | 1.3 - 1.5 | 逻辑+存储器 |
| 模拟模块 | 1.5 - 2.0 | 需要保护带 |

**3. 布线资源预估**

```
布线轨道需求 = (标准单元高度 × 单元数 × 引脚因子) / 金属层效率

引脚因子: 2.5 - 3.5 (取决于连接密度)
金属层效率: 0.7 - 0.8 (考虑 DRC 限制)
```

#### 拥塞预估方法

**1. 全局拥塞预估**

```tcl
# 基于布线资源计算
report_routing_resources

# 预估拥塞度
拥塞度 = 已用轨道数 / 总轨道数

目标值：
- 28nm: < 80%
- 16nm: < 75%
- 7nm: < 70%
```

**2. 局部拥塞预估**

```
局部拥塞 = 模块内单元密度 × 布线复杂度

布线复杂度：
- 简单逻辑: 1.0
- 中等复杂度: 1.2
- 高复杂度: 1.5 (高位宽总线、多端口存储器)
```

#### 模块摆放规划

**1. 数据流驱动摆放**

```
输入 → 模块A → 模块B → 模块C → 输出
       (靠近)   (靠近)   (靠近)

原则：数据流方向紧凑摆放
```

**2. 时钟域分组**

```
时钟域A 模块：
- CPU核心
- 缓存

时钟域B 模块：
- DDR控制器
- 外设接口

原则：同时钟域模块靠近摆放
```

**3. 功耗密度平衡**

```
高功耗模块分散摆放：
- CPU核心 (分散四角)
- DSP模块 (分散摆放)
- 存储器阵列 (均匀分布)

避免热点：
- 功耗密度 > 1W/mm² 需要散热考虑
```

#### 预估检查清单

- [ ] 总面积预估合理（与综合结果对比）
- [ ] 布线资源足够（拥塞度 < 目标值）
- [ ] 模块摆放规划完成
- [ ] 数据流路径最短
- [ ] 时钟域分组正确
- [ ] 功耗密度分布合理
- [ ] IR 降预估满足要求

---

### 阶段 2：Floorplan

**步骤：**
1. 设置芯片核心尺寸（core area）
2. IO 摆放（按 package 要求）
3. 电源环/电源带创建
4. PDN（电源分布网络）创建
5. 模块 hard macro 摆放
6. 标准模块区域划分

**检查清单 ✅**

- [ ] 总面积满足项目要求
- [ ] PDN IR 降满足要求（< 5% Vdd）
- [ ] PDN 电迁移满足要求
- [ ] 模块摆放符合数据流方向
- [ ] 硬宏模块避开电源带
- [ ] IO 摆放符合 package 要求
- [ ] 留出足够通道方便走线

**Floorplan 最佳实践：**

- 高吞吐量数据通路摆放紧凑，减少线长
- 存储器摆放靠近 IO，减少延迟
- 时钟模块放在芯片中心方便分发
- 电源 pad 均匀分布，减少 IR 降

### Floorplan 详细流程与命令

#### ICC2 Floorplan 命令

```tcl
# ============================================
# 1. 创建 Floorplan
# ============================================

# 设置芯片尺寸和核心区域
initialize_floorplan -core_utilization 0.7 \
                     -core_aspect_ratio 1.0 \
                     -core_margins {{left 10} {right 10} {top 10} {bottom 10}}

# 或者直接指定尺寸
initialize_floorplan -core_area {0 0 1000 1000}

# ============================================
# 2. IO 摆放
# ============================================

# 自动摆放 IO
place_pins -self

# 手动摆放 IO
set_pin_physical_constraint -pins {pin_name} -layers {M4} -sides {1}

# 按约束文件摆放
read_io_constraints io_constraints.iof

# ============================================
# 3. 电源环创建
# ============================================

# 创建电源环
create_pg_ring_pattern ring_pattern \
    -horizontal_layer M8 \
    -vertical_layer M9 \
    -horizontal_width {2.0} \
    -vertical_width {2.0} \
    -horizontal_spacing {0.5} \
    -vertical_spacing {0.5}

set_pg_strategy ring_strategy \
    -pattern {{name: ring_pattern} {nets: {VDD VSS}} \
    -core_offset {{inter_semiconductor_space: 1.0}}}

create_pg_mesh_region ring_strategy

# ============================================
# 4. 电源带创建
# ============================================

# 创建电源带
create_pg_mesh_pattern mesh_pattern \
    -horizontal_layer M6 \
    -vertical_layer M7 \
    -horizontal_width {0.5} \
    -vertical_width {0.5} \
    -horizontal_pitch {50} \
    -vertical_pitch {50}

# ============================================
# 5. Hard Macro 摆放
# ============================================

# 设置 Macro 约束
set_macro_constraint -allowed_orientations {R0 R180 MX MY}

# 手动摆放 Macro
place_cell -inst_name macro_inst1 -location {100 200} -orientation R0

# 自动摆放 Macro
place_macros

# 设置 Macro Keepout
create_keepout_margin -type hard -outer {5 5 5 5} macro_inst1
```

#### Innovus Floorplan 命令

```tcl
# ============================================
# Innovus Floorplan 流程
# ============================================

# 设置设计
loadDesign design.dc

# 创建 floorplan
floorPlan -coreUtilization 0.7 \
          -coreAspect 1.0 \
          -coreMargin 10

# 或者指定尺寸
floorPlan -site core -d 1000 1000 10 10 10 10

# IO 摆放
loadIoFile io_constraints.iof

# 创建电源环
addRing -nets {VDD VSS} \
        -layer {top M8 bottom M8 left M9 right M9} \
        -width 2.0 \
        -spacing 0.5 \
        -offset 1.0

# 创建电源带
addStripe -nets {VDD VSS} \
          -layer M6 \
          -direction horizontal \
          -width 0.5 \
          -spacing 0.5 \
          -set_to_set_distance 50

# Macro 摆放
placeInstance macro_inst1 100 200 R0

# 创建 blockage
createPlaceBlockage -type hard -boundary {{0 0} {100 100}}
```

#### OpenROAD Floorplan 命令

```tcl
# ============================================
# OpenROAD Floorplan 流程
# ============================================

# 初始化 floorplan
initialize_floorplan -utilization 0.7 \
                     -aspect_ratio 1.0 \
                     -core_space 10

# IO 摆放
place_pins -hor_layers M4 -ver_layers M3

# 创建电源网格
add_global_connection -net VDD -pin_pattern {VDD} -power
add_global_connection -net VSS -pin_pattern {VSS} -ground

# 电源网格定义
define_pdng_grid -name grid1 \
                 -starts_with POWER \
                 -layers {M8 M9} \
                 -widths 2.0 \
                 -pitches 100

# Macro 摆放
place_macro -macro_name macro_inst1 -x 100 -y 200 -orientation R0
```

#### Floorplan 常见问题与解决

| 问题 | 原因 | 解决方法 |
|------|------|----------|
| 面积过大 | 利用率设置过低 | 提高利用率，重新规划 |
| 拥塞严重 | Macro 摆放过密 | 调整 Macro 间距，增加通道 |
| IR 降过大 | 电源网格不足 | 增加电源带宽，减少间距 |
| 时序不收敛 | Macro 位置不合理 | 根据 dataflow 重新摆放 |

---

### 阶段 3：Placement

**步骤：**
1. 全局 placement（global placement）
2. 详细 placement（detailed placement）
3. 拥塞优化
4. 时序优化 placement

**检查清单 ✅**

- [ ] 布线拥塞在合理范围（< 80% 密度）
- [ ] 初始 WNS 满足初步要求（> 0 最好，至少不太多负slack）
- [ ] 没有超长网表（net length 太大）
- [ ] 硬宏周围密度合理，不拥塞

**拥塞过高怎么办？**

1. 重新摆放大模块，分散开
- 给大总线留出专用通道
- 分解超大模块为多个小模块
- 降低局部模块密度，留出空间

### Placement 详细流程与命令

#### ICC2 Placement 命令

```tcl
# ============================================
# 1. 全局 Placement
# ============================================

# 设置 placement 目标
set_placement_spacing_label -name S -side both -lib_cells [get_lib_cells]

# 运行全局 placement
place_opt -from initial

# 或者分步执行
legalize_placement -incremental

# ============================================
# 2. 拥塞分析
# ============================================

# 检查拥塞
report_congestion

# 查看详细拥塞
report_congestion -layers {M1 M2 M3 M4 M5 M6}

# 生成拥塞热点报告
report_congestion -hotspot

# ============================================
# 3. 拥塞优化
# ============================================

# 如果拥塞严重，增加目标密度
set_placement_spacing_label -name S -side both -lib_cells [get_lib_cells]
set_placement_density_limit 0.75

# 拥塞驱动的 placement
place_opt -congestion_effort high

# 使用 padding 缓解拥塞
set_placement_padding -global -left 2 -right 2

# ============================================
# 4. 时序驱动 Placement
# ============================================

# 使能时序优化
set_optimize_effort -high

# 运行时序驱动的 placement
place_opt -from initial -timing_effort high

# 检查初始时序
report_timing -max_paths 10
```

#### Innovus Placement 命令

```tcl
# ============================================
# Innovus Placement 流程
# ============================================

# 全局 placement
placeDesign -inplace_opt

# 拥塞分析
routeDesign -globalDetailRoute -congestionMapOnly

# 查看拥塞
encounter 13> win select CongestionViewer
encounter 14> congestionViewer -showCongestion

# 拥塞优化
setPlaceMode -timingDriven true -congestion true
placeDesign

# 时序检查
reportTiming

# 优化 placement
optDesign -preCTS
```

#### Placement 检查清单

| 检查项 | 目标值 | 检查方法 |
|--------|--------|----------|
| 全局拥塞 | < 5% | report_congestion |
| 局部拥塞 | < 80% | report_congestion -hotspot |
| 初始 WNS | > -500ps | report_timing |
| 最大线长 | 合理范围 | report_net_lengths |
| 单元密度 | < 85% | report_design_density |

#### Placement 常见问题与解决

| 问题 | 现象 | 解决方法 |
|------|------|----------|
| 拥塞热点 | 局部密度 > 90% | 增加 padding，调整 Macro 位置 |
| 时序差 | WNS < -1ns | 使能 timing-driven placement |
| 线长过长 | 关键路径延迟大 | 调整权重，优化关键路径摆放 |
| 重叠 | 单元重叠 | 运行 legalize_placement |

---

### 阶段 4：CTS（时钟树综合）

**步骤：**
1. 时钟树目标设置（skew 目标，latency 目标）
2. 时钟树综合
3. 时钟树优化（skew 优化，power 优化）
4. 时钟树验证

**目标：**

| 指标 | 目标 |
|------|------|
| 时钟 skew | < 100ps (先进工艺) |
| 时钟 latency | 满足设计要求 |
| 转换时间 | < 最大允许值 |
| 时钟功耗 | 在预算内 |

**检查清单 ✅**

- [ ] 时钟 skew 满足要求
- [ ] 时钟 latency 满足要求
- [ ] 转换时间满足要求
- [ ] 功耗满足要求
- [ ] 没有未平衡的时钟端点

**CTS 最佳实践：**

- 异步时钟域分开做 CTS，不要平衡
- 门控时钟正确识别，不要缓冲门控输出
- 使用有用skew优化改善时序

### CTS 详细流程与命令

#### ICC2 CTS 命令

```tcl
# ============================================
# 1. 时钟树设置
# ============================================

# 定义时钟
create_clock -name clk -period 10 [get_ports clk]

# 设置时钟树目标
set_clock_tree_options -target_skew 0.1
set_clock_tree_options -target_max_latency 2.0
set_clock_tree_options -target_min_latency 0.5

# 设置时钟树约束
set_clock_tree_constraints -max_transition 0.2
set_clock_tree_constraints -max_capacitance 0.5

# ============================================
# 2. 时钟树综合
# ============================================

# 综合时钟树
clock_tree_synthesis

# 或者使用 opt 设计
compile_clock_tree

# ============================================
# 3. 时钟树分析
# ============================================

# 报告时钟树状态
report_clock_tree -status

# 报告时钟 skew
report_clock_tree -skew

# 报告时钟 latency
report_clock_tree -latency

# 详细报告
report_clock_timing -type summary

# ============================================
# 4. 时钟树优化
# ============================================

# skew 优化
optimize_clock_tree -skew

# power 优化
optimize_clock_tree -power

# latency 优化
optimize_clock_tree -latency

# ============================================
# 5. 时钟树验证
# ============================================

# 检查时钟树
check_clock_tree

# 验证时钟网络
verify_clock_tree
```

#### Innovus CTS 命令

```tcl
# ============================================
# Innovus CTS 流程
# ============================================

# 创建时钟
createClock -name clk -period 10 [getPorts clk]

# 设置 CTS 目标
setCCOptTarget -skew 0.1
setCCOptTarget -maxLatency 2.0

# 运行 CTS
ccopt_design

# 分析时钟树
report_ccopt_clock_trees

# 验证
verifyClockNets
```

#### CTS 时钟树质量指标

| 指标 | 定义 | 目标值 |
|------|------|--------|
| Clock Skew | 同一时钟域内时钟到达时间差 | < 100ps (先进工艺) |
| Clock Latency | 时钟从源到寄存器的延迟 | 满足设计约束 |
| Insertion Delay | 时钟树插入延迟 | 越小越好，但需平衡 |
| Transition Time | 时钟信号转换时间 | < 最大允许值 |
| Clock Power | 时钟网络功耗 | 在预算内 |

#### CTS 常见问题与解决

| 问题 | 原因 | 解决方法 |
|------|------|----------|
| Skew 过大 | 时钟树不平衡 | 增加平衡 buffer，调整树结构 |
| Latency 过大 | 时钟树级数太多 | 减少级数，使用更大驱动 |
| 功耗过大 | 时钟网络负载大 | 使用门控时钟，减少翻转 |
| Transition 过大 | 驱动能力不足 | 增加 buffer，使用更大驱动 |

---

### 阶段 5：Routing

**步骤：**
1. 全局布线（global routing）
2. 详细布线（detailed routing）
3. 搜索修复布线失败
- 天线修复

**检查清单 ✅**

- [ ] 100% 布线完成（没有 unroute net）
- [ ] 没有绕线失败
- [ ] 所有天线违反修复完成
- [ ] 短路开路检查通过

**常见问题修复：**

- **布线失败**：局部拥塞 → 重新摆放模块增加通道
- **天线违反**：跳线到上层，或者插入天线二极管
- **短路**：检查重叠过孔，检查间距

### Routing 详细流程与命令

#### ICC2 Routing 命令

```tcl
# ============================================
# 1. 全局布线
# ============================================

# 检查布线拥塞
report_route_quality

# 设置布线层约束
set_ignored_layers -min_layer M1 -max_layer M8

# 全局布线
route_global

# ============================================
# 2. 详细布线
# ============================================

# 运行详细布线
route_auto

# 或分步执行
route_track
route_detail

# ============================================
# 3. 天线修复
# ============================================

# 检查天线违反
report_antenna_violations

# 自动修复天线违反
route_opt -repair_antenna

# 插入天线二极管
insert_antenna_diodes -all

# ============================================
# 4. 布线优化
# ============================================

# 优化布线
route_opt -size_only

# 修布线 DRC
route_opt -drc_effort high

# ============================================
# 5. 布线验证
# ============================================

# 检查布线完成度
report_route_status

# 检查未布线网络
report_unconnected_nets

# 检查短路和开路
verify_routing
```

#### Innovus Routing 命令

```tcl
# ============================================
# Innovus Routing 流程
# ============================================

# 设置布线层
setNanoRouteMode -drouteMinLayer M1
setNanoRouteMode -drouteMaxLayer M8

# 全局布线
globalDetailRoute

# 详细布线
detailRoute

# 天线修复
setNanoRouteMode -drouteFixAntenna true
routeDesign

# 检查布线
verifyConnectivity
verifyGeometry
```

#### Routing 检查清单

| 检查项 | 目标 | 命令 |
|--------|------|------|
| 布线完成率 | 100% | report_route_status |
| 天线违反 | 0 | report_antenna_violations |
| 短路 | 0 | verify_routing |
| 开路 | 0 | verify_routing |
| DRC 违反 | 0 | verify_geometry |

---

### 阶段 6：Timing Closure

**步骤：**
1. 静态时序分析
2. 识别最差路径
3. 修复建立时间违例
4. 修复保持时间违例
5. 迭代，直到所有满足

**优化优先级**

1. **满足建立时间**（所有工艺角）
2. **满足保持时间**（所有工艺角）
3. **修复所有违例**（转换时间，电容负载）

**检查清单 ✅**

- [ ] 所有工艺角 WNS ≥ 0
- [ ] 所有工艺角 TNS = 0
- [ ] 保持时间所有路径满足
- [ ] 没有最大转换时间违反
- [ ] 没有最大电容负载违反
- [ ] OCV 分析满足要求

### Timing Closure 详细流程与命令

#### ICC2 时序优化命令

```tcl
# ============================================
# 1. 时序分析
# ============================================

# 基本时序报告
report_timing -max_paths 10

# 详细时序报告
report_timing -max_paths 10 -delay_type max -input_pins -nets -caps

# 建立/保持时间报告
report_timing -delay_type max -max_paths 10  # 建立
report_timing -delay_type min -max_paths 10  # 保持

# 报告 WNS/TNS
report_timing -summary

# ============================================
# 2. 修复建立时间违例
# ============================================

# 自动优化
opt_design -post_route

# 具体优化策略
# 2.1 增加驱动
size_cell -cell_name <cell> -new_cell <larger_cell>

# 2.2 复制高扇出
clone_cell -cell_name <cell>

# 2.3 重新摆放关键路径
place_opt -timing_effort high -critical_path_endpoints

# 2.4 有用偏斜
set_clock_latency -max 0.2 [get_clocks clk] -source
set_clock_latency -min 0.1 [get_clocks clk] -source

# ============================================
# 3. 修复保持时间违例
# ============================================

# 自动修复
opt_design -post_route -hold

# 插入延迟单元
insert_buffer -cell_name <buffer_cell> -net <net_name>

# 调整驱动大小（用更小驱动）
size_cell -cell_name <cell> -new_cell <smaller_cell>

# ============================================
# 4. 多工艺角分析
# ============================================

# 设置工艺角
set_operating_conditions -analysis_type on_chip_variation

# 运行多工艺角分析
report_timing -corners {ss ff tt}

# OCV 分析
set_timing_derate -early 0.9 -cell_delay
set_timing_derate -late 1.1 -cell_delay
report_timing -max_paths 10
```

#### Innovus 时序优化命令

```tcl
# ============================================
# Innovus 时序优化流程
# ============================================

# 时序报告
reportTiming

# 建立时间优化
optDesign -postCTS -setup

# 保持时间优化
optDesign -postCTS -hold

# 后布线优化
optDesign -postRoute -setup -hold

# 多工艺角
setAnalysisMode -analysisType onChipVariation
reportTiming -corners {ss ff tt}
```

#### 时序收敛决策树

```
时序违例
    │
    ├── 建立时间违例 (Setup Violation)
    │       │
    │       ├── 组合逻辑延迟太大？
    │       │       ├── 是 → 流水线分割
    │       │       └── 否 → 继续分析
    │       │
    │       ├── 驱动不足？
    │       │       ├── 是 → 增加驱动
    │       │       └── 否 → 继续分析
    │       │
    │       ├── 线长太长？
    │       │       ├── 是 → 重新摆放
    │       │       └── 否 → 有用偏斜
    │       │
    │       └── 高扇出？
    │               └── 是 → 复制寄存器
    │
    └── 保持时间违例 (Hold Violation)
            │
            ├── 路径太快？
            │       ├── 是 → 插入延迟单元
            │       └── 否 → 继续分析
            │
            ├── 时钟偏斜问题？
            │       ├── 是 → 调整有用偏斜
            │       └── 否 → 增加线长
            │
            └── 驱动过大？
                    └── 是 → 减小驱动
```

---

### 阶段 7：物理验证

**必须做：**

1. **DRC**（设计规则检查）→ 零违反才能流片
2. **LVS**（版图原理图比对）→ 零违反才能流片
3. **ERC**（电学规则检查）
4. **天线检查**
5. **密度检查**
6. **IR 降分析**
7. **电迁移分析**

**检查清单 ✅**

- [ ] DRC 零违反
- [ ] LVS 零违反
- [ ] ERC 零违反
- [ ] 密度满足要求
- [ ] IR 降满足要求
- [ ] 电迁移满足要求

---

### 阶段 8：出带（tapeout）

**生成：**

- [ ] GDSII 完整芯片
- [ ] LEF/DEF 交换文件
- [ ] SPEF 寄生参数
- [ ] 最终网表
- [ ] 时序报告
- [ ] 所有检查报告

**文档：**

- 汇总报告（面积、时序、功耗）
- 违例汇总（如果有必须的waiver）
- GDS 层级说明

## 优化目标优先级

优先级从高到低：

1. **满足时序要求**（建立时间 + 保持时间，所有工艺角）
2. **满足物理验证**（设计规则零违反）
3. **满足功耗预算**
4. **最小化面积**

## 常见问题调试

### 问题 1：拥塞过高

**解决方法：**

1. **重新摆放模块**：把拥塞区域模块分散开
2. **留出通道**：给大总线和数据通路留出专用通道
3. **分解大模块**：超大模块分解成多个小模块
4. **降低密度**：增加芯片面积一点点，降低局部密度
5. **移除没用的逻辑**：删除死代码减少单元

### 问题 2：建立时间违例

**解决方法（按效果排序）：**

1. **流水线重分割**：把长组合逻辑分成多个流水级 → 最有效
2. **换更大驱动**：增加驱动强度减少延迟
3. **复制高扇出驱动**：大扇出复制多个寄存器减少负载每个
4. **重新摆放**：重新摆放减少关键路径线长
5. **有用偏斜调整**：调整寄存器时钟偏斜改善
6. **retiming**：移动寄存器边界平衡路径

### 问题 3：保持时间违例

**解决方法：**

1. **插入延迟单元**：在快路径插入延迟单元增加延迟
2. **调整有用偏斜**：调整发射时钟延迟增加路径延迟
3. **减小驱动**：用更小驱动增加延迟
- **重新摆放**：增加线长增加延迟

**重要：** 修复保持时间后必须重新检查建立时间，修复保持可能影响建立。

### 问题 4：DRC 违反

**解决方法：**

1. 在工具 GUI 定位错误位置
2. 看违反类型：间距/宽度/密度/天线
3. 分析原因：
   - **间距违反**：移动图形，增加间距
   - **密度违反**：添加填充金属
   - **天线违反**：跳线，插入二极管
   - **过孔违反**：重新排列过孔，增加间距

### 问题 5：LVS 错误

**常见 LVS 错误：**

- **端口不匹配**：网表端口和版图端口数量不同 → 检查顶层端口连接
- **节点短路**：两个应该分开的节点连在一起 → 检查层次，检查电源环切口
- **节点开路**：应该连接的没连上 → 检查blockage是否挡住连接
- **浮动节点**：节点没有连接 → 检查是否真的没用，没用删除

## 工具选择

| 任务 | 商业工具 | 开源工具 |
|------|----------|----------|
| 布局布线 | IC Compiler II (Synopsys), Innovus (Cadence) | OpenROAD |
| 静态时序分析 | PrimeTime (Synopsys), Tempus (Cadence) | OpenSTA |
| 物理验证 | Calibre (Siemens), ICV (Synopsys), PVS (Cadence) | - |

## 检查清单（tapeout 前最终检查）

- [ ] 所有工艺角建立时间满足（WNS ≥ 0）
- [ ] 所有工艺角保持时间满足
- [ ] DRC 零违反
- [ ] LVS 零违反
- [ ] IR 降满足要求
- [ ] 电迁移满足要求
- [ ] 功耗满足预算
- [ ] 面积满足预算
- [ ] GDS 正确层级
- [ ] 所有文档齐全

## 反模式（要避免）

❌ **跳过检查**："先流片回来再说" → 流片回来错了几百万就没了
❌ **忽略保持时间**：建立时间对了就完事 → 保持时间错了芯片不工作
❌ **不检查所有工艺角**：只检查典型工艺角 → 最坏情况不满足
❌ **电源规划太早不优化** → IR 降不够时序都错了
❌ **最后一分钟做大改动** → 引入新错误，没时间验证

## 代理协作

- 使用 `physical-design-engineer` 代理进行物理设计实现
- 使用 `timing-analysis` 技能进行时序分析和修复
- 使用 `power-analysis` 技能进行功耗和 IR 降分析
- 使用 `physical-design-engineer` 代理进行物理验证问题调试

