3. Cell与Instance:从设计蓝图到芯片实体的桥梁

各位工程师朋友,今天我们来聊聊版图设计里最基础、也最核心的一对概念——Cell和Instance。说实话,我刚入行那会儿,也经常把这两个东西搞混。后来带项目做多了,才真正体会到它们就像乐高积木里的「零件」和「拼装位置」的关系。

3.1 Cell的概念:设计的「原子」

Cell,中文叫「单元」或「细胞」。你可以把它理解成版图设计的最小功能模块。一个Cell里包含了完整的版图信息——有源区、多晶硅、金属层、接触孔,还有对应的逻辑功能。

我习惯把Cell比作一个「黑盒子」。你不需要关心里面长什么样,只要知道它的端口(Pin)在哪里,功能是什么,就够了。比如一个反相器Cell,你看到输入端和输出端,知道它能取反,这就行了。

Cell有几个关键属性:

  • 几何信息:各层的图形、尺寸、间距
  • 端口定义:输入、输出、电源、地
  • 逻辑功能:与门、或门、触发器……
  • 物理约束:最小间距、天线规则等

重要概念:Cell是「定义」,不是「实体」。就像建筑设计图,图纸本身不是房子,但房子要按图纸来建。

3.2 Instance的概念:设计的「实例化」

Instance,就是你把一个Cell「放」到版图里的具体位置。说白了,Instance是Cell的一次具体使用。

举个例子。你设计了一个反相器Cell叫INV_X1。现在你要在芯片里用10个反相器,怎么办?你不会画10遍,而是把INV_X1这个Cell「实例化」10次。每次实例化,就是一个Instance。

每个Instance都有自己独特的属性:

  • 坐标位置:在版图里的X、Y值
  • 旋转方向:0度、90度、180度、270度
  • 镜像状态:是否做镜像翻转
  • 实例名称:比如U1、U2、U3……

我的经验:在大型项目中,我习惯给Instance起有意义的名称,比如U_CPU_CLK_GATE、U_MEM_CTRL。别小看这个习惯,调试的时候能省一半时间。

3.3 Cell与Instance的关系:图纸与实物的区别

两者的关系,我用一张图来说明:

Cell(定义) INV_X1 反相器版图 AND2_X1 与门版图 • 几何图形定义 • 端口位置定义 • 逻辑功能定义 • 只存在一次 Instance(实例) U1 INV_X1 U2 INV_X1 U3 AND2_X1 • 具体位置坐标 • 旋转/镜像状态 • 引用Cell定义 • 可以存在多次

看到这张图了吗?左边是Cell的定义区,每个Cell只定义一次。右边是Instance的摆放区,同一个Cell可以被实例化多次,放在不同位置。

核心关系就三点:

  1. 一对多:一个Cell可以被实例化成无数个Instance
  2. 数据共享:所有Instance共享Cell的版图数据,不重复存储
  3. 独立属性:每个Instance有自己的位置、方向,但几何形状来自Cell

避坑指南:我曾经犯过一个低级错误——修改了一个Instance的版图,以为只改这一个。结果发现所有Instance都变了。为什么?因为Instance本身不存版图数据,它只是指向Cell的指针。要改单个Instance,你得先把它「打散」成独立的Cell。

3.4 创建Cell与Instance:动手实操

在华大九天的工具里,创建Cell和Instance的操作其实很直观。我带你走一遍流程。

3.4.1 创建Cell

创建Cell有两种方式:

方式 操作步骤 适用场景
新建空白Cell File → New → Cell → 输入名称、尺寸 从零开始设计标准单元
从已有Cell派生 选中Cell → Copy → 重命名 → 修改 在现有设计上做变体

我个人更推荐第二种方式。你想想看,从零画一个反相器要半天,但拿现成的改改尺寸、调调驱动能力,半小时就搞定了。

3.4.2 创建Instance

创建Instance就更简单了:

// 伪代码示例:在顶层版图中实例化一个反相器
// 1. 打开顶层版图
// 2. 选择菜单:Create → Instance
// 3. 在弹出的对话框中:
//    - Library: my_lib
//    - Cell: INV_X1
//    - View: layout
//    - Name: U_INV_1
//    - Location: (100, 200)
//    - Rotation: R0
// 4. 点击Place,完成实例化

实际操作中,你还可以用快捷键。我记得华大九天的工具里,默认快捷键是 I 键调出Instance创建窗口。用熟了以后,基本就是「I → 选Cell → 点位置 → 搞定」,三秒钟一个Instance。

3.4.3 批量实例化技巧

做大型项目时,手动一个个放Instance太慢了。我教你一个技巧:

  • 阵列摆放:选中Cell,用阵列功能一次性生成M×N个Instance
  • 脚本化:用Tcl脚本批量创建,适合规则排列的单元
  • 自动布局:调用布局工具,让工具帮你决定Instance的位置

我的习惯:在项目初期,我会先建一个「Cell清单」表格,把要用到的所有Cell列出来,包括尺寸、功耗、延迟。然后对照清单去创建Instance,这样不容易漏,也不会搞混。

3.5 层级关系:Cell套Cell

这里有个进阶概念——Cell里可以包含Instance。也就是说,一个Cell的内部,可以引用其他Cell的Instance。

举个例子:

  • 你有一个基础Cell:INV_X1(反相器)
  • 你创建了一个Cell:DFF_X1(触发器),里面实例化了6个INV_X1和4个传输门
  • 你在顶层版图里,实例化了100个DFF_X1

这样一层层嵌套下去,就形成了层次化设计。好处很明显:

  • 数据量小:底层Cell只存一次,顶层只存引用
  • 修改方便:改底层Cell,所有引用自动更新
  • 管理清晰:每个层级职责明确,便于团队协作

关键理解:Cell和Instance的关系,本质上是「类与对象」的关系。Cell是类,Instance是对象。你定义一个类,可以new出无数个对象。每个对象有自己的内存地址(坐标),但共享类的代码(版图数据)。

嗯,说到这里,我想起一个项目。当时有个同事把整个芯片画成了一个巨大的Cell,没有用任何Instance。结果芯片面积一改,他得手动调整几千个图形的位置,加班加了一个月。后来我帮他重构,把重复模块做成Cell,用Instance来拼,三天就改完了。

所以,我的建议是:多用Cell,少画重复图形。刚开始可能觉得建Cell麻烦,但后期改版的时候,你就知道省了多少事。


公众号:蓝海资料掘金营,微信deep3321