共计 1453 个字符,预计需要花费 4 分钟才能阅读完成。
作为集成电路设计新手,经常被 MCP 和 SKILL 这两个概念搞得晕头转向。今天我就结合自己在 Cadence Virtuoso 平台上的实践经验,给大家梳理一下它们的核心区别和使用场景。

概念对比:MCP vs SKILL
先来看一个直观的对比表格,帮助大家快速建立基本认知:
| 特性维度 | MCP (Multi-Chip Package) | SKILL 脚本语言 |
|---|---|---|
| 数据类型 | 强类型(明确 wire/net 定义) | 动态类型(自动推断) |
| 流程控制 | 硬件描述语言特性(并行执行) | 过程式编程(顺序执行) |
| EDA 集成度 | 主要用于物理层设计 | 全工具链支持(从原理图到验证) |
| 典型应用 | 芯片间互连设计 | 设计自动化脚本 |
| 调试方式 | 波形仿真 | 交互式 REPL 环境 |
新手常见踩坑点
在实际使用中,我发现有几个特别容易混淆的场景:
- 端口连接语法 :
- MCP 要求严格的端口映射格式,比如:
connect top.chip1.pin1 -> bottom.chip2.pin2 // 正确写法 -
而用 SKILL 的 list 操作会直接报错:
list(top.chip1.pin1 bottom.chip2.pin2) // 这在 MCP 环境无效 -
变量作用域 :
- SKILL 的动态变量可能造成意外覆盖:
let((x 1)) (println x) ; 这里 x =1 (let ((x 2)) ; 内层作用域 (println x)) ; 这里 x =2 -
MCP 的所有连接关系都是显式声明的
-
工具链支持 :
- Calibre 验证时,MCP 设计需要转成 GDSII 格式
- SKILL 脚本生成的修改则直接作用于设计数据库
实战代码示例
MCP 模块化设计示例
这个例子展示如何用 MCP 建立芯片间连接:
// 定义顶层封装
package system_package {
// 声明两个子芯片
chip cpu_die (
input clock,
output[31:0] data_bus
);
chip mem_die (input[31:0] addr_bus,
inout[31:0] data_bus
);
// 建立互连
connect cpu_die.data_bus -> mem_die.data_bus;
connect external_clock -> cpu_die.clock;
}
SKILL 自动化脚本示例
这段脚本批量修改元件属性:
/* 选中所有电阻器件 */
resistors = setof(inst cv~>instances
inst~>master~>name=="resistor")
/* 统一修改阻值为 1kΩ */
foreach(inst resistors
dbSetInstProp(inst "resistance" "1k")
printf("Modified %s\n" inst~>name)
)
工具链处理差异
在 Calibre 物理验证阶段:
- MCP 设计流 :
- 需要导出为 GDSII/OASIS 格式
-
运行 DRC 时需特别指定多芯片间距规则
-
SKILL 修改流 :
- 脚本修改实时反映在数据库中
- 验证前需要手动保存设计变更
避坑指南
根据我的踩坑经验,总结了三个关键技巧:
- 作用域隔离 :
-
写复杂 SKILL 脚本时,用 let() 明确限定变量作用域
-
类型检查 :
-
MCP 设计完成后用 virtuoso 的 Connectivity Check 功能验证
-
版本控制 :
- SKILL 脚本建议用 Git 管理,避免意外覆盖
选择决策树
最后分享一个简单的决策流程图:
是否需要物理连接?是 → 用 MCP
否 → 需要自动化操作?是 → 用 SKILL
否 → 直接 GUI 操作
经过这段时间的实践,我的体会是:MCP 更适合做芯片间的物理架构设计,而 SKILL 则是提高效率的自动化利器。刚开始可能会觉得语法差异很大,但熟悉后会发现它们其实是互补的好搭档。
正文完
发表至: 集成电路设计
近一天内
