共计 2197 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要 Pcell?
在模拟电路设计中,晶体管(transistor)是最基础的构建模块。传统手动绘制版图(manual layout)存在明显痛点:

- 每次尺寸变更都需要重新绘制所有图层
- 无法快速生成 finger 结构等重复图案
- 设计规则检查(DRC)错误需要人工逐个修正
参数化单元(Parameterized Cell,简称 Pcell)通过 skill 脚本实现:
- 尺寸参数动态计算(如 W / L 变化自动调整有源区)
- 智能规避 DRC 规则(如接触孔间距自动适应)
- 支持复杂结构一键生成(如 multi-finger、guard ring)
实际项目中,使用 Pcell 可使版图修改效率提升 5 -10 倍。
Skill 几何绘图核心 API
Skill 语言操作版图的核心函数(以 Virtuoso 为例):
; 创建矩形(layerName purpose width height x y)dbCreateRect(libId cellId viewId "OD" "drawing" w l x y)
; 创建多边形(需提供坐标点列表)dbCreatePolygon(libId cellId viewId "PO" "drawing" list(x1 y1 x2 y2...))
; 创建接触孔阵列(行列数自动计算)dbCreateContact(libId cellId viewId "CO" "drawing" x y rowCnt colCnt rowSpacing colSpacing)
实战:参数化 MOS 晶体管
以下代码演示生成 1 -finger NMOS 晶体管(关键参数已变量化):
procedure(createNMOS(libName cellName viewName w l fingerCnt)
let((libId cellId viewId (dx 0) (dy 0))
; 打开或创建单元
unless(libId = ddGetObj(libName) libId = dbCreateLib(libName))
unless(cellId = dbOpenCellViewByType(libName cellName viewName "maskLayout" "w")
cellId = dbCreateCellView(libName cellName viewName))
; 有源区绘制(自动扩展 STI 边缘)dx = w + 0.12 ; 默认 STI 包围 0.06um
dy = l + 0.12
dbCreateRect(libId cellId viewId "OD" "drawing" dx dy -dx/2 -dy/2)
; 多晶硅栅极(支持 finger 参数)repeat(fingerCnt 1
dbCreateRect(libId cellId viewId "PO" "drawing" w 0.05 -w/2 (n*0.1)-0.025)
)
; 自动计算接触孔阵列(考虑最小间距规则)contactWidth = 0.05
contactSpacing = 0.07
cols = floor((w - contactWidth)/(contactWidth + contactSpacing)) + 1
rows = 2 ; 标准双排接触
dbCreateContact(libId cellId viewId "CO" "drawing"
-w/4 l/4 rows cols contactSpacing contactSpacing)
dbCreateContact(libId cellId viewId "CO" "drawing"
w/4 -l/4 rows cols contactSpacing contactSpacing)
)
)
代码优化要点:
- 使用
let局部变量避免污染全局命名空间 - 通过
unless条件判断减少重复创建风险 - 接触孔行列数动态计算适配不同 W /L
生产环境避坑指南
PDK 版本兼容性
不同工艺 PDK 可能存在的差异:
- 图层名称变化(如 ”PO” 可能变为 ”POLY1″)
- 设计规则数值调整(如接触孔最小间距)
解决方案:
; 通过 techGetTechFile 获取当前工艺规则
contactSpacing = techGetTechFile("minContactSpacing")
单位制转换
Virtuoso 内部使用数据库单位(DBU),通常:
- 1 DBU = 0.001 micron(65nm 及以上工艺)
- 1 DBU = 0.0005 micron(28nm 及以下工艺)
建议始终使用 dbConvertToDBU/dbConvertFromDBU 函数转换:
; 将 0.1um 转换为 DBU
dbConvertToDBU(0.1)
调试技巧
启用 skill 调试模式查看运行时信息:
- 在 CIW 窗口输入:
deBugMode = t - 使用
println输出变量值:printf("当前 W =%.3f um\n" dbConvertFromDBU(w)) - 通过
axlShell直接测试代码片段
进阶思考
-
LOD 效应补偿:如何在 Pcell 中实现长度依赖氧化层(Length-Oxide-Dependent)的哑元栅极(dummy gate)自动插入?
-
多 finger 优化:当 finger 数 >10 时,如何优化源漏共享区域的接触孔分布以减少寄生电阻?
-
Pcells 联动:若需要构建差分对管,如何实现两个 Pcell 实例的自动对称摆放和衬底连接?
结语
掌握 Pcell 开发能力后,可以大幅提升模拟版图设计效率。建议从简单晶体管开始,逐步尝试复杂结构如 bipolar、电阻阵列等。遇到问题时多利用 axlHelp 函数查阅文档,或通过 Cadence 社区寻求支持。
